Documentation
¶
Index ¶
- Constants
- func Field(name string) *substitutions.SubstitutionPathItem
- func Index(index int) *substitutions.SubstitutionPathItem
- func MakeRef(newResourceName string, path []*substitutions.SubstitutionPathItem) *substitutions.Substitution
- func PathExact(ref *substitutions.SubstitutionResourceProperty, fieldPathSegments ...string) bool
- func PathMatches(ref *substitutions.SubstitutionResourceProperty, fieldPathSegments ...string) bool
- func RegisterEmit[T any, PR ResolvedPtr[T]](reg *TransformerRegistry, target Target, ...)
- func RegisterRewriter[T any, PR ResolvedPtr[T]](reg *TransformerRegistry, target Target, ...)
- func RetargetRef(ref *substitutions.SubstitutionResourceProperty, newResourceName string) *substitutions.Substitution
- func RewriteBlueprintRefs(blueprint *schema.Blueprint, visitor subwalk.SubstitutionVisitor) *schema.Blueprint
- func RewriteFields(ref *substitutions.SubstitutionResourceProperty, newResourceName string, ...) *substitutions.Substitution
- func RewriteResourcePropertyRefs(rewriter ResourcePropertyRewriter) subwalk.SubstitutionVisitor
- func RunTransformPipeline(inputBlueprint *schema.Blueprint, linkGraph linktypes.DeclaredLinkGraph, ...) (*transform.SpecTransformerTransformOutput, error)
- func TransformerBaseAnnotations(input *TransformerBaseAnnotationsInput) *schema.StringOrSubstitutionsMap
- func ValueRef(valueName string, path ...*substitutions.SubstitutionPathItem) *substitutions.Substitution
- type Aggregator
- type Capabilities
- type EmitPlan
- type EmitResult
- type Emitter
- type EmitterRegistration
- type PropertyMap
- type PropertyRule
- type ResolvedPtr
- type ResolvedResource
- type Resolver
- type ResourcePropertyRewriter
- type RewriteContext
- type RewriteFactory
- type RewriterRegistration
- type SharedParent
- type Target
- type TransformerBaseAnnotationsInput
- type TransformerRegistry
- func (r *TransformerRegistry) AggregatorFor(target Target) (Aggregator, bool)
- func (r *TransformerRegistry) CapabilitiesFor(target Target, resolvedType reflect.Type) (Capabilities, bool)
- func (r *TransformerRegistry) EmitterFor(target Target, resolvedType reflect.Type) (Emitter, bool)
- func (r *TransformerRegistry) HasAggregators() bool
- func (r *TransformerRegistry) IsEmpty() bool
- func (r *TransformerRegistry) MergeFrom(other *TransformerRegistry)
- func (r *TransformerRegistry) RegisterAggregator(target Target, aggregator Aggregator)
- func (r *TransformerRegistry) RegisterResolver(abstractResourceType string, resolver Resolver)
- func (r *TransformerRegistry) ResolverFor(abstractResourceType string) (Resolver, bool)
- func (r *TransformerRegistry) RewriteFactoryFor(target Target, resolvedType reflect.Type) (RewriteFactory, bool)
- type ValueRefSpec
Constants ¶
const ( // AnnotationSourceAbstractName is the annotation key set by transformer plugins // to record the original abstract resource name that a concrete resource was // expanded from. AnnotationSourceAbstractName = "bluelink.transform.source.abstractName" // AnnotationSourceAbstractType is the annotation key set by transformer plugins // to record the original abstract resource type that a concrete resource was // expanded from. AnnotationSourceAbstractType = "bluelink.transform.source.abstractType" // AnnotationResourceCategory is the annotation key set by transformer plugins // to classify a concrete resource as either "code-hosting" or "infrastructure". // Used by the code-only auto-approval mechanism. AnnotationResourceCategory = "bluelink.transform.resourceCategory" // ResourceCategoryCodeHosting indicates a resource that hosts application code // (e.g. Lambda function, ECS task, API Gateway). ResourceCategoryCodeHosting = "code-hosting" // ResourceCategoryInfrastructure indicates an infrastructure dependency // (e.g. DynamoDB table, S3 bucket, IAM role, VPC). ResourceCategoryInfrastructure = "infrastructure" )
Variables ¶
This section is empty.
Functions ¶
func Field ¶
func Field(name string) *substitutions.SubstitutionPathItem
Field is sugar for a literal field-name path item:
&SubstitutionPathItem{FieldName: name}.
func Index ¶
func Index(index int) *substitutions.SubstitutionPathItem
Index is sugar for a literal array-index path item:
&SubstitutionPathItem{ArrayIndex: &index}.
func MakeRef ¶
func MakeRef( newResourceName string, path []*substitutions.SubstitutionPathItem, ) *substitutions.Substitution
MakeRef is a low-level constructor that builds a SubstitutionResourceProperty pointing at newResourceName with the given path. The caller assembles the path explicitly from Field / Index items and (where useful) slices of ref.Path. Used for cases that don't fit RewriteFields' 1:1 model.
func PathExact ¶
func PathExact( ref *substitutions.SubstitutionResourceProperty, fieldPathSegments ...string, ) bool
PathExact returns true if the ref's path matches the given field names exactly (ignoring array indices between field names).
func PathMatches ¶
func PathMatches( ref *substitutions.SubstitutionResourceProperty, fieldPathSegments ...string, ) bool
PathMatches returns true if the ref's path starts with the given field path segments, ignoring array indices. Useful for prefix matching on nested structures.
For example:
ref: spec.vpc.securityGroups[0].id fieldPathSegments: "spec", "vpc", "securityGroups" returns: true (matches the prefix of the path, ignoring indices)
func RegisterEmit ¶
func RegisterEmit[T any, PR ResolvedPtr[T]]( reg *TransformerRegistry, target Target, fn func(r PR, resPropRewriter ResourcePropertyRewriter, transformCtx transform.Context) (*EmitResult, error), )
RegisterEmit is a generic helper to register an emitter for a specific target, ensuring type safety on the resolved type.
The registry is keyed by the pointer type *T (PR), not the value type T, because aggregators put *T values into EmitPlan.Primaries — so reflect.TypeOf(primary) at emit-lookup time is the pointer type, and the registration key must match.
func RegisterRewriter ¶
func RegisterRewriter[T any, PR ResolvedPtr[T]]( reg *TransformerRegistry, target Target, fn func(r PR) []ResourcePropertyRewriter, )
RegisterRewriter is a generic helper to register a rewrite factory for a specific target, ensuring type safety on the resolved type. Keyed by *T (PR) for the same reason as RegisterEmit — primaries are pointer-typed at lookup time.
func RetargetRef ¶
func RetargetRef( ref *substitutions.SubstitutionResourceProperty, newResourceName string, ) *substitutions.Substitution
RetargetRef returns a SubstitutionResourceProperty identical to ref but pointing at newResourceName. The path (including array indices) is preserved. Use when only the resource name changes.
func RewriteBlueprintRefs ¶
func RewriteBlueprintRefs( blueprint *schema.Blueprint, visitor subwalk.SubstitutionVisitor, ) *schema.Blueprint
RewriteBlueprintRefs returns a shallow copy of blueprint with every substitution-bearing top-level section walked by visitor. Sections walked:
- Exports[*] — every value (direct field reference, not in ${..}) and description StringOrSubstitutions
- Values[*] — every value and description StringOrSubstitutions
- Include[*] — path, variables, metadata, description
- DataSources[*] — filter search values, metadata, description
- Metadata — top-level free-form mapping
Sections passed through unchanged (no substitution support as per spec):
- Variables, Version
Resources and Transform are also passed through here; the transformer owns those separately:
- Resources: spec-level rewrites happen inline during per-resource emit, where each emitter has access to resource-specific structural transformations (memory -> memorySize, etc.). The driver replaces this section wholesale with emitted output.
- Transform: the transformer strips its own identifier from this list.
Returns a shallow copy — the input blueprint is not mutated, but pointer-shared sub-trees that weren't rewritten remain shared.
func RewriteFields ¶
func RewriteFields( ref *substitutions.SubstitutionResourceProperty, newResourceName string, newFields ...string, ) *substitutions.Substitution
RewriteFields is a declarative high-level helper to be used by transformers when rewriting references to resource properties.
It can rename fields in ref.Path one-to-one, with N-dimensional array indices auto-preserved at their original relative positions. The i-th field-name item in ref.Path becomes newFields[i]; index items sandwiched between fields are kept at the same relative slot (between the renamed fields they followed). Source items beyond len(newFields) field positions are appended unchanged.
Examples (paths shown logically; "[i]" stands for any source array index):
.spec.memory -> .spec.memorySize
newFields = "spec", "memorySize"
.spec.routes[i].method -> .spec.paths[i].httpMethod
newFields = "spec", "paths", "httpMethod" (one-dimensional)
.spec.rules[i].targets[j].arn -> .spec.rules[i].destinations[j].arn
newFields = "spec", "rules", "destinations", "arn" (two-dimensional)
Extra field names beyond the original path are appended. Use MakeRef when the rewrite needs to insert or remove fields, restructure nesting depth (e.g. environmentVariables -> environment.variables), or introduce literal array indices that don't exist in the source path.
func RewriteResourcePropertyRefs ¶
func RewriteResourcePropertyRefs(rewriter ResourcePropertyRewriter) subwalk.SubstitutionVisitor
RewriteResourcePropertyRefs builds a SubstitutionVisitor from a ResourcePropertyRewriter. Only SubstitutionResourceProperty substitutions are passed to the rewriter; all other substitution types pass through.
func RunTransformPipeline ¶
func RunTransformPipeline( inputBlueprint *schema.Blueprint, linkGraph linktypes.DeclaredLinkGraph, target Target, transformerID string, registry *TransformerRegistry, transformCtx transform.Context, ) (*transform.SpecTransformerTransformOutput, error)
RunTransformPipeline drives the framework's transformer pipeline for plugins that don't provide their own TransformFunc implementation.
func TransformerBaseAnnotations ¶
func TransformerBaseAnnotations( input *TransformerBaseAnnotationsInput, ) *schema.StringOrSubstitutionsMap
TransformerBaseAnnotations returns base annotations to be used for concrete resources generated from an abstract resource type to maintain correlation between the abstract resource in your blueprint and the concrete resources that will be deployed.
func ValueRef ¶
func ValueRef( valueName string, path ...*substitutions.SubstitutionPathItem, ) *substitutions.Substitution
ValueRef returns a SubstitutionValueReference. With no path items it is the flat form ${values.<name>}; trailing path items target a nested field or array element when the transformer-generated value is a complex object or list. Path items are built with Field / Index, identical to resource refs.
Examples:
ValueRef("ordersHandler_lambda_arn")
-> ${values.ordersHandler_lambda_arn}
ValueRef("ordersDb_connection", Field("host"))
-> ${values.ordersDb_connection.host}
ValueRef("api_endpoints", Index(0), Field("url"))
-> ${values.api_endpoints[0].url}
Types ¶
type Aggregator ¶
type Aggregator func([]ResolvedResource) *EmitPlan
Aggregator is a function that produces an emit plan from a list of resources resolved for a particular abstract resource type.
type Capabilities ¶
type Capabilities struct {
// SupportedAbstractPaths is the set of dot notation abstract
// property paths this (target, resource-type) pair handles.
// This is generated from a PropertyMap.
SupportedAbstractPaths []string
}
func CapabilitiesFromPropertyMap ¶
func CapabilitiesFromPropertyMap(pm *PropertyMap) *Capabilities
CapabilitiesFromPropertyMap derives a Capabilities struct from a property map's rename and value reference paths.
type EmitPlan ¶
type EmitPlan struct {
// Primaries are the main resolved resources that will be emitted as concrete output.
Primaries []ResolvedResource
// that don't correspond to any single abstract input.
// This lets pre-primary emits populate shared parents incrementally so
// partial-fold targets (e.g. Azure Function, Cloud Run, VPC Connector)
// can produce per-resource outputs and shared resource output in the same
// pass without giving up the the per-primary 1:1 mapping that a full fold
// implementation would otherwise require.
SharedParents []SharedParent
}
EmitPlan represents the output of the aggregation phase that is fed into the concrete output emission phase.
type EmitResult ¶
type EmitResult struct {
Resources map[string]*schema.Resource
DerivedValues map[string]*schema.Value
// Mapping of shared parent key to the contributions
// from all resources that share this parent.
Diagnostics []*core.Diagnostic
}
EmitResult represents the output of the emission phase for a single resolved resource.
type Emitter ¶
type Emitter func( r ResolvedResource, resPropRewriter ResourcePropertyRewriter, transformCtx transform.Context, ) (*EmitResult, error)
Emitter produces concrete output for one resolved primary for a specific target.
type EmitterRegistration ¶
type EmitterRegistration func(registry *TransformerRegistry, t Target)
EmitterRegistration is a deferred registration closure that captures the concrete resolved type. This is necessary to allow authors to write their emitters with concrete resolved types while maintaing a valid homogenous map value type for emitter storage in registries.
func TypedEmitter ¶
func TypedEmitter[T any, PR ResolvedPtr[T]]( fn func( r PR, resPropRewriter ResourcePropertyRewriter, transformCtx transform.Context, ) (*EmitResult, error), ) EmitterRegistration
TypedEmitter is a generic helper to produce an EmitterRegistration for a specific target, ensuring type safety on the resolved type. This is intended for use in AbstractResourceDefinition.Emitters maps.
type PropertyMap ¶
type PropertyMap struct {
// Renames contains simple 1:1 mappings of abstract property name to concrete property name.
// The key is a dotted abstract path and value consists of concrete path
// segments. Array indices in the abstract path are auto-preserved at their
// original positions (RewriteFields semantics).
Renames map[string][]string
// ValueRefs contains mappings of abstract refs that should redirect to
// a transformer-derived value. For example, a composite abstract value
// derived from multiple concrete resource properties.
// The key is a dotted abstract path and values describe the value reference.
ValueRefs map[string]*ValueRefSpec
// Custom contains custom rules that don't fit into the rename
// or value-ref categories.
Custom []*PropertyRule
}
PropertyMap is a declarative description of how an abstract resource's substitution-referenceable properties map to a target's concrete equivalents. The majority of cases will be 1:1 renames and value-ref redirects; a small number of cases will involve structural reshapes or literal index injections.
func (*PropertyMap) Rewriter ¶
func (pm *PropertyMap) Rewriter(abstractName, concreteName string) ResourcePropertyRewriter
Rewriter materialises the PropertyMap as a ResourcePropertyRewriter closure parameterised with the abstract ↔ concrete name pair from one resolved primary.
Renames / ValueRefs key splits and Custom MatchPaths patterns are pre-compiled once per closure so per-ref dispatch is O(rules) without repeated string parsing.
type PropertyRule ¶
type PropertyRule struct {
// MatchPaths is the path-pattern set this rule handles.
// Patterns may contain "[*]" to match an array index (e.g. "spec.vpc.securityGroups[*].id").
// MatchPaths is the single source of truth for both runtime matching and capabilitiy extraction.
MatchPaths []string
// Predicate is an optional further filter beyond the path match.
// Most rules will only need match paths and leave this as nil.
// When defined, the rule applies only if the substitution's path
// matches one of MatchPaths AND Predicate returns true.
// Predicate-conditional matches are intentionally outside the capabilities
// scope (capabilities are purely path-based); document conditional
// behaviour via abstract resource or link definitions for users and your
// own developer guidance for future maintainers.
Predicate func(*substitutions.SubstitutionResourceProperty) bool
// Rewrite produces the new substitution if the rule matches.
Rewrite func(
ref *substitutions.SubstitutionResourceProperty,
rewriteCtx RewriteContext,
) *substitutions.Substitution
}
PropertyRule describes a custom rule for rewriting a resource property reference that doesn't fit into the rename or value-ref categories. The Match function determines whether the rule applies to a given reference, and the Rewrite function produces the new substitution if it does.
type ResolvedPtr ¶
type ResolvedPtr[T any] interface { *T ResolvedResource }
ResolvedPtr is a generic helper interface to ensure type safety on resolved resource types. Concrete resolved types implement ResolvedResource with pointer receivers, so the constraint is expressed via ResolvedPtr[T]; "PR is *T and *T satisfies ResolvedResource".
type ResolvedResource ¶
ResolvedResource is the target-agnostic output of the resolve phase that is fed into aggregation, rewriting and emission. Concrete resource types (e.g. *ResolvedQueue, *ResolvedHandler) live in their resource packages and implement this interface.
type Resolver ¶
type Resolver func( name string, resource *schema.Resource, linkGraph linktypes.DeclaredLinkGraph, blueprint *schema.Blueprint, ) (ResolvedResource, error)
Resolver is a target-agnostic resolver for a single abstract resource type. These resolvers are keyed by abstract resource type in a transformer registry and are not tied to any specific target.
type ResourcePropertyRewriter ¶
type ResourcePropertyRewriter func( ref *substitutions.SubstitutionResourceProperty, ) *substitutions.Substitution
ResourcePropertyRewriter is called for each SubstitutionResourceProperty found during traversal. It receives the full SubstitutionResourceProperty (resource name, property path at any depth, template index) and returns: - A replacement *Substitution (any variant: resource ref, value ref, etc.) - nil to keep the original unchanged
func ChainResourcePropertyRewriters ¶
func ChainResourcePropertyRewriters( rewriters ...ResourcePropertyRewriter, ) ResourcePropertyRewriter
ChainResourcePropertyRewriters combines multiple rewriters into one. The first rewriter to return a non-nil substitution wins.
type RewriteContext ¶
RewriteContext provides contextual information for custom property rewrite rules.
type RewriteFactory ¶
type RewriteFactory func(r ResolvedResource) []ResourcePropertyRewriter
RewriteFactory produces a list of rewriters from on resolved primary. Returns multiple for compound primaries (e.g. a ResolvedService folding in N handlers + M apis, contributes to N+M rewriters).
type RewriterRegistration ¶
type RewriterRegistration func(registry *TransformerRegistry, t Target)
RewriterRegistration is a deferred registration closure that captures the concrete resolved type for rewriters. This is necessary to allow authors to write their rewriters with concrete resolved types while maintaing a valid homogenous map value type for rewriter storage in registries.
func RewriterFromPropertyMap ¶
func RewriterFromPropertyMap[T any, PR ResolvedPtr[T]]( pm *PropertyMap, concreteName func(r PR) string, ) RewriterRegistration
RewriterFromPropertyMap produces a RewriterRegistration that wraps a PropertyMap in a single-rewriter factory. The concreteName function derives the concrete resource name for one resolved primary; this is the per-target piece of information that the PropertyMap itself can't carry (different targets name the same abstract resource differently — _sqs, _lambda, _topic, etc.).
Side effect: also registers a capability-matrix entry for (target, *T) derived from the same PropertyMap, so pre-emit reference validation and authoring docs see the supported abstract paths without authors having to do anything else. The capability matrix and the rewriter share the same PropertyMap as a single source of truth.
Use this as the typical declarative path for AbstractResourceDefinition.Rewriters when the rewriting is fully described by a PropertyMap. For compound primaries or multi-rewriter contributions, use TypedRewriter with a hand-written factory instead — capability matrix entries for those cases must be supplied via the Registry overlay.
func TypedRewriter ¶
func TypedRewriter[T any, PR ResolvedPtr[T]]( fn func(r PR) []ResourcePropertyRewriter, ) RewriterRegistration
TypedRewriter is a generic helper to produce a RewriterRegistration for a specific target, ensuring type safety on the resolved type. This is intended for use in AbstractResourceDefinition.Rewriters maps.
type SharedParent ¶
type SharedParent struct {
}
SharedParent represents a declared concrete output resource that doesn't correspond to a single abstract input resource.
type Target ¶
type Target string
Target represents a deployment target such as "aws-serverless" or "azure".
type TransformerBaseAnnotationsInput ¶
type TransformerBaseAnnotationsInput struct {
// AbstractResourceName is the name of the abstract resource in the blueprint.
AbstractResourceName string
// AbstractResourceType is the type of the abstract resource in the blueprint.
AbstractResourceType string
// ResourceCategory is the category of the resource, either "code-hosting" or "infrastructure".
ResourceCategory string
}
type TransformerRegistry ¶
type TransformerRegistry struct {
// contains filtered or unexported fields
}
func NewTransformerRegistry ¶
func NewTransformerRegistry() *TransformerRegistry
func (*TransformerRegistry) AggregatorFor ¶
func (r *TransformerRegistry) AggregatorFor(target Target) (Aggregator, bool)
AggregatorFor looks up the aggregator for a given target.
func (*TransformerRegistry) CapabilitiesFor ¶
func (r *TransformerRegistry) CapabilitiesFor( target Target, resolvedType reflect.Type, ) (Capabilities, bool)
CapabilitiesFor looks up the capability matrix entry for a given target and resolved resource type. Used by pre-emit reference validation (Pillar 4) and tooling that renders authoring docs.
func (*TransformerRegistry) EmitterFor ¶
func (r *TransformerRegistry) EmitterFor( target Target, resolvedType reflect.Type, ) (Emitter, bool)
EmitterFor looks up the emitter for a given target and resolved resource type.
func (*TransformerRegistry) HasAggregators ¶
func (r *TransformerRegistry) HasAggregators() bool
HasAggregators reports whether the registry has at least one aggregator registered. Used by the framework's first-use validation to confirm that a pipeline-mode plugin has at least one aggregator across the union of TransformerPluginDefinition.Aggregators and the Registry overlay.
func (*TransformerRegistry) IsEmpty ¶
func (r *TransformerRegistry) IsEmpty() bool
IsEmpty reports whether the registry holds zero registrations across all dimensions (resolvers, aggregators, emitters, rewriters, capabilities). Used by the framework to decide whether a non-nil overlay registry actually contributes anything to the pipeline-detection signal.
func (*TransformerRegistry) MergeFrom ¶
func (r *TransformerRegistry) MergeFrom(other *TransformerRegistry)
MergeFrom merges every registration from other into r. Collisions on any dimension (resolver abstract type, aggregator target, (target, resolved- type) emitter / rewriter / capability) panic with a "duplicate registration" message — this matches the original design's "Registry overlay collides with auto-derived registration" contract and keeps misconfig loud rather than silently overwriting one source with another.
A nil receiver panics; a nil other is a no-op.
func (*TransformerRegistry) RegisterAggregator ¶
func (r *TransformerRegistry) RegisterAggregator( target Target, aggregator Aggregator, )
RegisterAggregator registers an aggregator function for a given deployment target.
func (*TransformerRegistry) RegisterResolver ¶
func (r *TransformerRegistry) RegisterResolver( abstractResourceType string, resolver Resolver, )
RegisterResolver registers a resolver function for a given abstract resource type.
func (*TransformerRegistry) ResolverFor ¶
func (r *TransformerRegistry) ResolverFor(abstractResourceType string) (Resolver, bool)
ResolverFor looks up the resolver for a given abstract resource type.
func (*TransformerRegistry) RewriteFactoryFor ¶
func (r *TransformerRegistry) RewriteFactoryFor( target Target, resolvedType reflect.Type, ) (RewriteFactory, bool)
RewriteFactoryFor looks up the rewrite factory for a given target and resolved resource type.
type ValueRefSpec ¶
type ValueRefSpec struct {
// Suffix appended to the concrete resource name to form the value name.
// e.g. "_arn" -> ${values.<concreteName>_arn}
Suffix string
// Path is for complex derived values (e.g. {url, authType} objects).
// The path descends into the value. Empty path is a flat ref.
Path []*substitutions.SubstitutionPathItem
}
ValueRefSpec describes how to construct a value reference for a property that doesn't have a simple 1:1 mapping to a concrete resource property.