Expose sequence placement controls in the public API
This commit is contained in:
54
lifecycle.go
54
lifecycle.go
@@ -15,6 +15,37 @@ type Definition[T any] struct {
|
||||
Validate func(*T, *Validation)
|
||||
Version *VersionRule
|
||||
Secret func(Path) bool
|
||||
// SequenceCompositions registers mapping paths whose sequence contributions
|
||||
// strictly append distinct records by the selected literal identity field.
|
||||
// Repeated identities and conflicting registrations fail option validation.
|
||||
// Registration paths are copied when a load begins; definitions are read-only
|
||||
// after being shared.
|
||||
SequenceCompositions []SequenceComposition
|
||||
}
|
||||
|
||||
// PlacementMode selects how an input mapping is placed at its Destination.
|
||||
// The zero value, PlacementModeMapping, preserves ordinary mapping placement.
|
||||
// Unknown values and sequence-item placement at the root fail option validation.
|
||||
type PlacementMode uint8
|
||||
|
||||
const (
|
||||
// PlacementModeMapping places a source mapping at Destination.
|
||||
PlacementModeMapping PlacementMode = iota
|
||||
// PlacementModeSequenceItem wraps a source mapping as one item at Destination.
|
||||
PlacementModeSequenceItem
|
||||
)
|
||||
|
||||
// SequenceComposition registers a sequence path for strict identity-based
|
||||
// composition. Path is copied at load start; IdentityField is one literal key,
|
||||
// including the empty string. Invalid or conflicting registrations fail option
|
||||
// validation.
|
||||
type SequenceComposition struct {
|
||||
// Path selects a literal mapping path; registration paths are copied at load
|
||||
// start. Invalid paths fail option validation; the root path is harmless.
|
||||
Path Path
|
||||
// IdentityField is one literal mapping key and may be empty. Records must
|
||||
// contain a string at this key; malformed records fail strict composition.
|
||||
IdentityField string
|
||||
}
|
||||
|
||||
// SourceVersionMode controls schema-version declarations across one complete
|
||||
@@ -44,10 +75,17 @@ const (
|
||||
// Imports enables explicit path and glob imports; Overlay selects one fixed overlay;
|
||||
// Overrides contains only values explicitly supplied by an application CLI.
|
||||
// Enabled source-version modes interpret Definition.Version.Path in each
|
||||
// document's local coordinates. Main protection remains at that path prefixed
|
||||
// by the main input's Destination.
|
||||
// document's local coordinates. Placement projects checks and main protection
|
||||
// through the input destination; item placement adds the source's item
|
||||
// coordinate to that projection. See docs/config.md for the full contract.
|
||||
type Options[T any] struct {
|
||||
Definition Definition[T]
|
||||
Definition Definition[T]
|
||||
// Destination places the ordinary source beneath literal mapping keys. Its
|
||||
// zero value means the application root. Invalid paths fail before acquisition.
|
||||
Destination Path
|
||||
// PlacementMode defaults to mapping placement; unknown values and root item
|
||||
// placement fail before acquisition.
|
||||
PlacementMode PlacementMode
|
||||
Imports bool
|
||||
Overlay string
|
||||
Filesystem *FilesystemContext
|
||||
@@ -261,6 +299,7 @@ func toEngineOptions[T any](options Options[T]) engine.Options[T] {
|
||||
Overlay: options.Overlay,
|
||||
SourceVersionMode: engine.SourceVersionModeFromFacade(uint8(options.SourceVersionMode)),
|
||||
}
|
||||
result = engine.OptionsWithPlacement(result, toEnginePath(options.Destination.clone()), uint8(options.PlacementMode))
|
||||
if options.Filesystem != nil {
|
||||
result.Filesystem = toEngineFilesystemContext(options.Filesystem)
|
||||
}
|
||||
@@ -289,6 +328,15 @@ func toEngineFilesystemContext(context *FilesystemContext) *engine.FilesystemCon
|
||||
|
||||
func toEngineDefinition[T any](definition Definition[T]) engine.Definition[T] {
|
||||
result := engine.Definition[T]{Defaults: definition.Defaults}
|
||||
if definition.SequenceCompositions != nil {
|
||||
paths := make([]engine.Path, len(definition.SequenceCompositions))
|
||||
identityFields := make([]string, len(definition.SequenceCompositions))
|
||||
for index, registration := range definition.SequenceCompositions {
|
||||
paths[index] = toEnginePath(registration.Path.clone())
|
||||
identityFields[index] = registration.IdentityField
|
||||
}
|
||||
result = engine.DefinitionWithSequenceRegistrations(result, paths, identityFields)
|
||||
}
|
||||
if definition.Resolve != nil {
|
||||
result.Resolve = func(configuration *T, resolution *engine.Resolution) error {
|
||||
return definition.Resolve(configuration, &Resolution{value: resolution})
|
||||
|
||||
Reference in New Issue
Block a user