Documentation
¶
Index ¶
- func EvaluateAssertions(assertions []CompositeAssertion, rc extractors.ResponseContext) ([]spi.AssertionResult, error)
- func ExtractOutputs(outputs []Output, rc extractors.ResponseContext) (map[string]any, error)
- func NewOutputView(outputs map[string]map[string]any) spi.OutputView
- func NewSkippedResult(nodeType spi.Kind, base spi.BaseExecutionResult) (spi.AnyResult, bool)
- func RegisterNodeKind(nodeType spi.Kind, decode Decoder, newSkipped SkippedResultFactory)
- func ValidateOutputs(outputSchema []string, produced map[string]any) error
- type AnyNode
- type AssertData
- type AssertExecutionResult
- type AssertNode
- type AssertionContextProvider
- type BaseNode
- func (bn *BaseNode) GetAssertions() []CompositeAssertion
- func (bn *BaseNode) GetDisplayName() string
- func (bn *BaseNode) GetID() string
- func (bn *BaseNode) GetOutputs() []Output
- func (bn *BaseNode) GetRunWhen() spi.RunWhen
- func (bn *BaseNode) GetType() spi.Kind
- func (bn *BaseNode) InputSchema() []string
- func (bn *BaseNode) OutputSchema() []string
- type BranchCase
- type BranchData
- type BranchExecutionResult
- type BranchNode
- type CompositeAssertion
- type Decoder
- type DelayData
- type DelayExecutionResult
- type DelayNode
- type LoopData
- type LoopExecutionResult
- type LoopNode
- type ModuleData
- type ModuleExecutionResult
- type ModuleNode
- func (n *ModuleNode) DisplayName(name string) *ModuleNode
- func (n *ModuleNode) Execute(ctx spi.ExecutionContext) (spi.AnyResult, error)
- func (n *ModuleNode) GetData() ModuleData
- func (n *ModuleNode) InputBinding(key string, value any) *ModuleNode
- func (n *ModuleNode) InputSchema() []string
- func (n *ModuleNode) OutputBinding(parentName, childKey string) *ModuleNode
- func (n *ModuleNode) OutputSchema() []string
- type Output
- type PollData
- type PollExecutionResult
- type PollNode
- type RequestData
- type RequestExecutionResult
- type RequestNode
- func (n *RequestNode) Always() *RequestNode
- func (n *RequestNode) Assert(assertion CompositeAssertion) *RequestNode
- func (n *RequestNode) Body(body any) *RequestNode
- func (n *RequestNode) DELETE(url string) *RequestNode
- func (n *RequestNode) DisplayName(name string) *RequestNode
- func (n *RequestNode) Execute(ctx spi.ExecutionContext) (spi.AnyResult, error)
- func (n *RequestNode) GET(url string) *RequestNode
- func (n *RequestNode) GetAssertions() []CompositeAssertion
- func (n *RequestNode) GetData() RequestData
- func (n *RequestNode) GetOutputs() []Output
- func (n *RequestNode) Header(key, value string) *RequestNode
- func (n *RequestNode) InputSchema() []string
- func (n *RequestNode) Method(method, url string) *RequestNode
- func (n *RequestNode) Output(output Output) *RequestNode
- func (n *RequestNode) OutputSchema() []string
- func (n *RequestNode) PATCH(url string) *RequestNode
- func (n *RequestNode) POST(url string) *RequestNode
- func (n *RequestNode) PUT(url string) *RequestNode
- func (n *RequestNode) TimeoutMs(ms int) *RequestNode
- type SchemaInference
- type SetVariableData
- type SetVariableExecutionResult
- type SetVariableNode
- type SkippedResultFactory
- type SseData
- type SseExecutionResult
- type SseNode
- type TemplateResolver
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func EvaluateAssertions ¶
func EvaluateAssertions( assertions []CompositeAssertion, rc extractors.ResponseContext, ) ([]spi.AssertionResult, error)
EvaluateAssertions evaluates every assertion against rc, assigning each result its Index. Evaluation stops at the first failing or erroring assertion — that one IS recorded — and the corresponding error is returned. The returned slice holds results for all assertions up to and including the first failure (or all of them on success). This is the single assertion-evaluation implementation; every node delegates to it.
func ExtractOutputs ¶
func ExtractOutputs( outputs []Output, rc extractors.ResponseContext, ) (map[string]any, error)
ExtractOutputs runs every output extractor against rc, returning the produced name->value map. It fails fast on the first extractor error. This is the single output-extraction implementation; every node delegates to it.
func NewOutputView ¶
func NewOutputView(outputs map[string]map[string]any) spi.OutputView
func NewSkippedResult ¶
NewSkippedResult builds the skipped result for nodeType via the registry, reporting false when the type is unregistered.
func RegisterNodeKind ¶
func RegisterNodeKind(nodeType spi.Kind, decode Decoder, newSkipped SkippedResultFactory)
RegisterNodeKind registers how to decode a node type and build its skipped result. Call from an init().
func ValidateOutputs ¶
ValidateOutputs checks that every name in outputSchema was produced. It returns an error naming the first missing output. This is the single output-validation implementation; every node delegates to it.
Types ¶
type AnyNode ¶
type AnyNode interface {
spi.Node
// GetAssertions returns the list of assertions to validate during execution.
// Assertions should be evaluated before extractions.
GetAssertions() []CompositeAssertion
// GetOutputs returns the list of extractions to perform on the response/data.
// Outputs should be evaluated after assertions pass.
GetOutputs() []Output
}
AnyNode is the full authoring/engine view of a node: the capability-agnostic core (spi.Node) plus the assertion and output accessors, which carry concrete extractor decode/eval behavior and therefore stay in this package.
func UnmarshalNode ¶
UnmarshalNode unmarshals JSON into the appropriate typed node via the node-kind registry (see registry.go). Adding a node type is one RegisterNodeKind call, not a new case here.
type AssertData ¶
type AssertData struct {
// Target is the value the assertions/extractors run against. It may carry
// {{template}} or {{{raw}}} references that resolve to inputs/flow data. When
// nil/empty the node falls back to asserting over the flow's initial inputs
// (ctx.FlowInputs).
//
// To assert over an UPSTREAM NODE's output, set an explicit target that
// references it (e.g. "{{{create-user.payload}}}"); InputSchema surfaces that
// ref so the engine populates ctx.Inputs and the template resolves to the
// upstream value. An OMITTED target asserts over the flow's initial inputs
// (ctx.FlowInputs) — not over upstream node outputs.
Target any `json:"target,omitempty"`
}
AssertData configures an assert node. Target is the value to assert against; when empty the node asserts over the flow's initial inputs.
type AssertExecutionResult ¶
type AssertExecutionResult struct {
spi.BaseExecutionResult
DurationMs int64 `json:"duration_ms"`
// contains filtered or unexported fields
}
AssertExecutionResult stores assert node execution data: the value asserted over and the full set of assertion outcomes captured during evaluation.
func (*AssertExecutionResult) AssertionContext ¶
func (r *AssertExecutionResult) AssertionContext() extractors.ResponseContext
AssertionContext exposes the ResponseContext the engine-level assertion/output pass evaluates against. It satisfies AssertionContextProvider; a nil context (e.g. an error result built before the target was resolved) signals the engine to skip the pass.
type AssertNode ¶
type AssertNode struct {
BaseNode
Data AssertData `json:"data"`
// contains filtered or unexported fields
}
AssertNode validates upstream or derived data with the standard assertion list. Unlike RequestNode it runs assertions over an in-memory value rather than an HTTP response, making it a first-class way to verify data produced by earlier nodes (transforms, modules, branches) in an API-flow test.
To assert over an UPSTREAM NODE's output, set an explicit target referencing it (e.g. "{{{node.output}}}"); the omitted-target default instead asserts over the flow's initial inputs.
func AsAssertNode ¶
func AsAssertNode(node AnyNode) (*AssertNode, bool)
AsAssertNode safely casts an AnyNode to an AssertNode. Returns the AssertNode and true if the cast succeeds, nil and false otherwise.
func (*AssertNode) Execute ¶
func (n *AssertNode) Execute(ctx spi.ExecutionContext) (spi.AnyResult, error)
Execute resolves the target value and returns an AssertExecutionResult that exposes it as a ResponseContext (via AssertionContext). It does NOT run assertions or extract outputs itself: the engine-level pass drives those uniformly for every node that implements AssertionContextProvider (see engine.applyAssertionsAndOutputs), filling AssertionResults, merging outputs, and flipping the result to failed on a miss. Keeping the node thin means a single shared seam owns assertion/output evaluation and retry behavior.
func (*AssertNode) GetData ¶
func (n *AssertNode) GetData() AssertData
GetData returns the node's typed data.
func (*AssertNode) InputSchema ¶
func (n *AssertNode) InputSchema() []string
InputSchema infers inputs from template variables referenced in the target.
func (*AssertNode) OutputSchema ¶
func (n *AssertNode) OutputSchema() []string
OutputSchema returns the names of the declared output extractors.
type AssertionContextProvider ¶
type AssertionContextProvider interface {
AssertionContext() extractors.ResponseContext
}
AssertionContextProvider is the optional interface a node RESULT implements to expose the ResponseContext its assertions and outputs evaluate against. The engine drives the assertion/output pass uniformly for any result that implements it; results that do not (delay, module) are left untouched.
type BaseNode ¶
type BaseNode struct {
ID string `json:"id"`
DisplayName string `json:"display_name"`
NodeType spi.Kind `json:"type"`
RunWhen spi.RunWhen `json:"run_when,omitempty"`
Assertions []CompositeAssertion `json:"assertions"`
Outputs []Output `json:"outputs"`
}
BaseNode contains common fields and behavior shared across all node types. All specific node types (RequestNode, DelayNode, AssertionNode, etc.) should embed BaseNode.
func (*BaseNode) GetAssertions ¶
func (bn *BaseNode) GetAssertions() []CompositeAssertion
GetAssertions returns the list of assertions to validate during execution Assertions should be evaluated before extractions.
func (*BaseNode) GetDisplayName ¶
GetDisplayName returns the display name for this node.
func (*BaseNode) GetOutputs ¶
GetOutputs returns the list of extractions to perform on the response/data Outputs should be evaluated after assertions pass.
func (*BaseNode) GetRunWhen ¶
func (*BaseNode) InputSchema ¶
InputSchema returns the list of required inputs for this node This method must be overridden by concrete node types to provide computed schemas Format: "nodeId.outputKey" (e.g., "create-user.userId") or plain variable name.
func (*BaseNode) OutputSchema ¶
OutputSchema returns the list of outputs this node produces This method must be overridden by concrete node types to provide computed schemas Examples: []string{"statusCode", "userId", "responseBody"}.
type BranchCase ¶
type BranchCase struct {
When CompositeAssertion `json:"when"`
Target string `json:"target"`
}
BranchCase pairs a condition with the successor node ID to route to when the condition holds. When evaluates against the resolved branch target value (an in-memory value, not an HTTP response).
type BranchData ¶
type BranchData struct {
Target any `json:"target,omitempty"`
Cases []BranchCase `json:"cases"`
Default string `json:"default,omitempty"`
}
BranchData configures value-based routing.
- Target is an optional template; its resolved value is what the case conditions test. When omitted (nil), the branch tests the map of the node's resolved inputs (ctx.Inputs).
- Cases are evaluated in order; the first whose When passes selects its Target as the routed successor.
- Default is an optional successor node ID used when no case matches.
type BranchExecutionResult ¶
type BranchExecutionResult struct {
spi.BaseExecutionResult
// MatchedTarget is the successor node ID execution was routed to, or "" when
// no case matched and no default was configured.
MatchedTarget string `json:"matched_target"`
// RoutedTargetIDs holds the chosen successor node IDs (one element when a
// case/default matched, empty otherwise).
RoutedTargetIDs []string `json:"routed_targets"`
DurationMs int64 `json:"duration_ms"`
}
BranchExecutionResult stores value-based routing decision data. It implements spi.RoutingResult so the engine skips the successor subtrees the branch routed away from.
func (*BranchExecutionResult) RoutedTargets ¶
func (r *BranchExecutionResult) RoutedTargets() []string
RoutedTargets implements spi.RoutingResult, returning the successor node IDs this branch routed execution to.
type BranchNode ¶
type BranchNode struct {
BaseNode
Data BranchData `json:"data"`
// contains filtered or unexported fields
}
BranchNode routes execution down exactly one downstream path based on a condition evaluated over upstream data. Unlike spi.RunWhen (which gates on success/failure), a branch performs value-based routing: the chosen successor runs and the others are skipped by the engine.
func AsBranchNode ¶
func AsBranchNode(candidate AnyNode) (*BranchNode, bool)
AsBranchNode safely casts an AnyNode to a BranchNode.
func (*BranchNode) Execute ¶
func (n *BranchNode) Execute(ctx spi.ExecutionContext) (spi.AnyResult, error)
Execute evaluates the branch cases against the resolved target value and selects exactly one successor (or none). It never fails on a "no match" outcome — that is a valid routing decision recorded in the result.
func (*BranchNode) GetData ¶
func (n *BranchNode) GetData() BranchData
GetData returns the branch configuration.
func (*BranchNode) InputSchema ¶
func (n *BranchNode) InputSchema() []string
InputSchema infers inputs from template variables referenced in the optional target template.
func (*BranchNode) OutputSchema ¶
func (n *BranchNode) OutputSchema() []string
OutputSchema exposes the routing decision keys this node produces.
type CompositeAssertion ¶
type CompositeAssertion struct {
Extractor extractors.AnyExtractor `json:"-"` // The actual extractor instance
ExtractorType string `json:"extractorType"` // jsonPath, xmlPath, statusCode, header, body
OperatorType operators.OperatorType `json:"operatorType"` // equals, contains, greaterThan, etc.
ExpectedValue any `json:"-"` // Resolved expected value (operator_data.value)
}
CompositeAssertion combines an extractor with an operator for validation.
func (*CompositeAssertion) Evaluate ¶
func (ca *CompositeAssertion) Evaluate(ctx extractors.ResponseContext) spi.AssertionResult
Evaluate runs the assertion against the response and returns a full result record. Index is left zero for the caller to assign. Passed is true only when the extractor succeeds and the operator holds; Error is set (and Passed false, Actual possibly nil) when the extractor or operator errors. This is the single evaluation entry point — it both decides pass/fail and captures what was compared, so callers never re-derive the outcome.
func (*CompositeAssertion) UnmarshalJSON ¶
func (ca *CompositeAssertion) UnmarshalJSON(data []byte) error
UnmarshalJSON implements custom unmarshaling for CompositeAssertion.
type DelayData ¶
type DelayData struct {
Duration int `json:"duration"` // Duration in milliseconds
}
type DelayExecutionResult ¶
type DelayExecutionResult struct {
spi.BaseExecutionResult
DelayMs int64 `json:"delay_ms"`
DelayUntil time.Time `json:"delay_until"`
}
DelayExecutionResult stores delay node execution data.
type DelayNode ¶
DelayNode is a typed node for delays.
func (*DelayNode) DisplayName ¶
DisplayName sets the delay node's name.
func (*DelayNode) Execute ¶
Execute sleeps for the specified duration and returns a DelayExecutionResult.
func (*DelayNode) InputSchema ¶
InputSchema returns empty as DelayNode doesn't need inputs.
func (*DelayNode) OutputSchema ¶
OutputSchema returns empty as DelayNode doesn't produce outputs.
type LoopData ¶
type LoopData struct {
// Items is a template (or literal) that resolves to a []any. Each element is
// iterated over and the body sub-flow is run once per element.
Items any `json:"items"`
// Body is an inline flow definition ({"nodes":[...],"edges":[...]}) executed
// once per iteration via the shared spi.ModuleExecutor.
Body json.RawMessage `json:"body"`
// ItemVar is the FlowInputs key the current item is injected under (default "item").
ItemVar string `json:"item_var"`
// IndexVar is the FlowInputs key the current zero-based index is injected under
// (default "index").
IndexVar string `json:"index_var"`
// MaxIterations, when > 0, caps how many items are iterated as a safety bound.
MaxIterations int `json:"max_iterations"`
// ContinueOnError keeps the loop running when an iteration fails, recording the
// error in that iteration's result instead of failing the whole node.
ContinueOnError bool `json:"continue_on_error"`
}
LoopData configures a foreach loop node.
type LoopExecutionResult ¶
type LoopExecutionResult struct {
spi.BaseExecutionResult
// Iterations is the number of body executions that were attempted
// (after applying any max_iterations cap).
Iterations int `json:"iterations"`
DurationMs int64 `json:"duration_ms"`
// contains filtered or unexported fields
}
LoopExecutionResult stores foreach loop node execution data.
func (*LoopExecutionResult) AssertionContext ¶
func (r *LoopExecutionResult) AssertionContext() extractors.ResponseContext
AssertionContext exposes the ResponseContext the engine-level assertion/output pass evaluates against — the loop's aggregate outputs ({results, count}). It satisfies AssertionContextProvider; a nil context (e.g. an error result built before the loop completed) signals the engine to skip the pass.
type LoopNode ¶
LoopNode iterates a body sub-flow once per item in a resolved array (foreach), injecting the per-iteration item and index into the child flow inputs and collecting each iteration's final outputs into an array.
func AsLoopNode ¶
AsLoopNode safely casts an AnyNode to a LoopNode.
func (*LoopNode) Execute ¶
Execute resolves the items array and runs the body sub-flow once per item, injecting item/index into the child flow inputs and aggregating per-iteration final outputs into a results array.
func (*LoopNode) GetOutputs ¶
GetOutputs returns the loop's default aggregate extractors (results, count) followed by any user-declared outputs. A user-declared output with the same name overrides the default, so the loop's intrinsic outputs stay referenceable while remaining customizable.
func (*LoopNode) InputSchema ¶
InputSchema infers inputs from the items template only. Body references are validated inside the child flow parse, not by the parent loop node.
func (*LoopNode) OutputSchema ¶
OutputSchema lists every output the loop node produces: its intrinsic aggregates (results, count) plus any user-declared outputs.
type ModuleData ¶
type ModuleExecutionResult ¶
type ModuleExecutionResult struct {
spi.BaseExecutionResult
FlowID string `json:"flow_id"`
ChildFinalOutputs map[string]any `json:"child_final_outputs,omitempty"`
DurationMs int64 `json:"duration_ms"`
}
ModuleExecutionResult stores nested module execution data.
type ModuleNode ¶
type ModuleNode struct {
BaseNode
Data ModuleData `json:"data"`
}
ModuleNode executes another flow as a reusable nested module.
func AsModuleNode ¶
func AsModuleNode(candidate AnyNode) (*ModuleNode, bool)
AsModuleNode safely casts an AnyNode to a ModuleNode.
func (*ModuleNode) DisplayName ¶
func (n *ModuleNode) DisplayName(name string) *ModuleNode
DisplayName sets the module node's name.
func (*ModuleNode) Execute ¶
func (n *ModuleNode) Execute(ctx spi.ExecutionContext) (spi.AnyResult, error)
func (*ModuleNode) GetData ¶
func (n *ModuleNode) GetData() ModuleData
func (*ModuleNode) InputBinding ¶
func (n *ModuleNode) InputBinding(key string, value any) *ModuleNode
InputBinding binds a child-flow input to a value/template.
func (*ModuleNode) InputSchema ¶
func (n *ModuleNode) InputSchema() []string
InputSchema infers inputs from binding templates.
func (*ModuleNode) OutputBinding ¶
func (n *ModuleNode) OutputBinding(parentName, childKey string) *ModuleNode
OutputBinding maps a child final output key to a parent-visible output name.
func (*ModuleNode) OutputSchema ¶
func (n *ModuleNode) OutputSchema() []string
OutputSchema exposes the parent-visible outputs exported by the module node.
type Output ¶
type Output struct {
Name string `json:"name"`
Extractor extractors.AnyExtractor `json:"extractor"`
}
Output represents a named output with an associated extractor.
func (*Output) UnmarshalJSON ¶
UnmarshalJSON implements custom unmarshaling for Output This allows us to properly unmarshal the Extractor field from JSON.
type PollData ¶
type PollData struct {
// Body is an inline flow definition executed once per attempt. The exit
// condition (the node's assertions) is evaluated against its FinalOutputs.
Body json.RawMessage `json:"body"`
// MaxAttempts is the maximum number of body executions. Defaults to
// defaultPollMaxAttempts when <= 0.
MaxAttempts int `json:"max_attempts"`
// IntervalMs is the wait between attempts, in milliseconds. Defaults to
// defaultPollIntervalMs when <= 0.
IntervalMs int `json:"interval_ms"`
// TimeoutMs, when > 0, caps the overall wall-clock budget for the whole poll
// (layered on top of the execution context deadline).
TimeoutMs int `json:"timeout_ms"`
}
PollData configures a poll-until node. The body sub-flow is re-run on an interval until the node's exit-condition assertions (BaseNode.Assertions) all pass against an attempt's child final outputs, or the attempt/deadline budget is exhausted.
type PollExecutionResult ¶
type PollExecutionResult struct {
spi.BaseExecutionResult
// Attempts is the number of body executions performed (the attempt on which
// the poll succeeded, or the total attempts made before giving up).
//
// The exit-condition evaluation from the final attempt (the passing attempt on
// success, or the last attempt on failure) is recorded in the promoted
// BaseExecutionResult.AssertionResults field.
Attempts int `json:"attempts"`
DurationMs int64 `json:"duration_ms"`
}
PollExecutionResult stores poll-until node execution data. The poll node re-runs an inline body sub-flow on an interval until all of its exit-condition assertions pass on a single attempt, or it exhausts its attempt/deadline budget.
type PollNode ¶
PollNode re-runs an inline body flow on an interval until an exit-condition assertion holds — the canonical async-API pattern (kick off a job, then poll "status == done" before continuing).
func AsPollNode ¶
AsPollNode safely casts an AnyNode to a PollNode. Returns the PollNode and true if the cast succeeds, nil and false otherwise.
func MustAsPollNode ¶
MustAsPollNode casts an AnyNode to a PollNode, panicking if it fails. Use this when you're certain the node is a PollNode.
func (*PollNode) Execute ¶
Execute runs the body sub-flow up to max_attempts times, evaluating the exit-condition assertions against each attempt's child final outputs. It succeeds on the first attempt where all assertions pass; otherwise it waits interval_ms and retries until the attempt budget, timeout, or context deadline is exhausted.
func (*PollNode) InputSchema ¶
InputSchema returns empty: the poll node feeds the parent flow inputs into the body sub-flow rather than declaring named upstream dependencies.
func (*PollNode) OutputSchema ¶
OutputSchema exposes the keys the poll node produces on success.
type RequestData ¶
type RequestExecutionResult ¶
type RequestExecutionResult struct {
spi.BaseExecutionResult
// HTTP Request fields
RequestMethod string `json:"request_method"`
RequestURL string `json:"request_url"`
RequestHeaders map[string]string `json:"request_headers"`
RequestBody any `json:"request_body,omitempty"`
// HTTP Response fields
ResponseStatusCode int `json:"response_status_code"`
ResponseHeaders map[string][]string `json:"response_headers"`
ResponseBody []byte `json:"response_body,omitempty"`
ResponseBodyParsed any `json:"response_body_parsed,omitempty"`
// Timing
DurationMs int64 `json:"duration_ms"`
// contains filtered or unexported fields
}
RequestExecutionResult stores HTTP request node execution data.
func (*RequestExecutionResult) AssertionContext ¶
func (r *RequestExecutionResult) AssertionContext() extractors.ResponseContext
AssertionContext exposes the ResponseContext the engine-level assertion/output pass evaluates against. It satisfies AssertionContextProvider; a nil context (e.g. an error result built before the HTTP exchange completed) signals the engine to skip the pass.
type RequestNode ¶
type RequestNode struct {
BaseNode
Data RequestData `json:"data"`
// contains filtered or unexported fields
}
RequestNode is a typed node for HTTP requests.
func AsRequestNode ¶
func AsRequestNode(node AnyNode) (*RequestNode, bool)
AsRequestNode safely casts an AnyNode to a RequestNode Returns the RequestNode and true if the cast succeeds, nil and false otherwise.
func NewRequest ¶
func NewRequest(id string) *RequestNode
NewRequest starts a request node with the given id.
func (*RequestNode) Always ¶
func (n *RequestNode) Always() *RequestNode
Always marks the node to run in the cleanup phase even after a main-phase failure.
func (*RequestNode) Assert ¶
func (n *RequestNode) Assert(assertion CompositeAssertion) *RequestNode
Assert appends a validation assertion.
func (*RequestNode) Body ¶
func (n *RequestNode) Body(body any) *RequestNode
Body sets the request body (any JSON-serializable value, with {{var}} support).
func (*RequestNode) DELETE ¶
func (n *RequestNode) DELETE(url string) *RequestNode
DELETE is a shorthand for Method("DELETE", url).
func (*RequestNode) DisplayName ¶
func (n *RequestNode) DisplayName(name string) *RequestNode
DisplayName sets the human-readable name.
func (*RequestNode) Execute ¶
func (n *RequestNode) Execute(ctx spi.ExecutionContext) (spi.AnyResult, error)
func (*RequestNode) GET ¶
func (n *RequestNode) GET(url string) *RequestNode
GET is a shorthand for Method("GET", url).
func (*RequestNode) GetAssertions ¶
func (n *RequestNode) GetAssertions() []CompositeAssertion
func (*RequestNode) GetData ¶
func (n *RequestNode) GetData() RequestData
func (*RequestNode) GetOutputs ¶
func (n *RequestNode) GetOutputs() []Output
func (*RequestNode) Header ¶
func (n *RequestNode) Header(key, value string) *RequestNode
Header adds a request header (supports {{var}} templates).
func (*RequestNode) InputSchema ¶
func (n *RequestNode) InputSchema() []string
InputSchema infers inputs from template variables in URL, Headers, QueryParams, and Body.
func (*RequestNode) Method ¶
func (n *RequestNode) Method(method, url string) *RequestNode
Method sets the HTTP method + URL.
func (*RequestNode) Output ¶
func (n *RequestNode) Output(output Output) *RequestNode
Output appends an extracted output (referenced downstream as "id.name").
func (*RequestNode) OutputSchema ¶
func (n *RequestNode) OutputSchema() []string
OutputSchema infers outputs from the Outputs list.
func (*RequestNode) PATCH ¶
func (n *RequestNode) PATCH(url string) *RequestNode
PATCH is a shorthand for Method("PATCH", url).
func (*RequestNode) POST ¶
func (n *RequestNode) POST(url string) *RequestNode
POST is a shorthand for Method("POST", url).
func (*RequestNode) PUT ¶
func (n *RequestNode) PUT(url string) *RequestNode
PUT is a shorthand for Method("PUT", url).
func (*RequestNode) TimeoutMs ¶
func (n *RequestNode) TimeoutMs(ms int) *RequestNode
TimeoutMs sets the per-request timeout in milliseconds.
type SchemaInference ¶
type SchemaInference struct{}
SchemaInference provides utilities to infer input and output schemas from node configurations.
func (*SchemaInference) ExtractTemplateVariables ¶
func (si *SchemaInference) ExtractTemplateVariables(data any) []string
ExtractTemplateVariables extracts all {{variable}} references from a string or nested structure.
func (*SchemaInference) InferRequestNodeInputSchema ¶
func (si *SchemaInference) InferRequestNodeInputSchema(data RequestData) []string
InferRequestNodeInputSchema infers input schema from RequestNode data.
func (*SchemaInference) InferRequestNodeOutputSchema ¶
func (si *SchemaInference) InferRequestNodeOutputSchema(outputs []Output) []string
InferRequestNodeOutputSchema infers output schema from Outputs.
type SetVariableData ¶
SetVariableData configures a set-variable node. Each entry maps an output name to a template value: a string with {{a.b}} / {{x}} references, a number/bool, or a nested object/array that may contain {{{raw}}} structured references.
type SetVariableExecutionResult ¶
type SetVariableExecutionResult struct {
spi.BaseExecutionResult
DurationMs int64 `json:"duration_ms"`
}
SetVariableExecutionResult stores set-variable node execution data. The computed named values are exposed both as the node Outputs (via the embedded base) and as the engine sees them; DurationMs records resolution time.
func (*SetVariableExecutionResult) AssertionContext ¶
func (r *SetVariableExecutionResult) AssertionContext() extractors.ResponseContext
AssertionContext exposes the computed variables map (the node Outputs) as the ResponseContext the engine-level assertion/output pass evaluates against. This gives set-variable nodes free assertions over their resolved variables, satisfying AssertionContextProvider. A nil Outputs map (e.g. an error result) signals the engine to skip the pass.
type SetVariableNode ¶
type SetVariableNode struct {
BaseNode
Data SetVariableData `json:"data"`
}
SetVariableNode computes named outputs from upstream node outputs and flow inputs via template resolution, without performing any HTTP call. It is used to assemble payloads, derive headers, and reshape values between nodes.
func AsSetVariableNode ¶
func AsSetVariableNode(candidate AnyNode) (*SetVariableNode, bool)
AsSetVariableNode safely casts an AnyNode to a SetVariableNode. Returns the SetVariableNode and true if the cast succeeds, nil and false otherwise.
func (*SetVariableNode) Execute ¶
func (n *SetVariableNode) Execute(ctx spi.ExecutionContext) (spi.AnyResult, error)
Execute resolves every configured variable template against the node inputs and dynamic variables, returning the resolved values as the node outputs. No HTTP call or external side effect is performed.
func (*SetVariableNode) GetData ¶
func (n *SetVariableNode) GetData() SetVariableData
func (*SetVariableNode) InputSchema ¶
func (n *SetVariableNode) InputSchema() []string
InputSchema infers required inputs from the template variables referenced in the configured values, mirroring how ModuleNode derives inputs from bindings.
func (*SetVariableNode) OutputSchema ¶
func (n *SetVariableNode) OutputSchema() []string
OutputSchema exposes the names of the variables this node produces, sorted.
type SkippedResultFactory ¶
type SkippedResultFactory func(base spi.BaseExecutionResult) spi.AnyResult
SkippedResultFactory builds the kind's skipped execution result from a shared base, so the engine doesn't switch on node type to construct skips.
type SseData ¶
type SseData struct {
// URL is the event-stream endpoint (templated).
URL string `json:"url"`
// Method defaults to GET when empty.
Method string `json:"method"`
// Headers are sent on the request (values templated).
Headers map[string]string `json:"headers"`
// MaxEvents stops the stream after N events (default defaultSseMaxEvents).
MaxEvents int `json:"max_events"`
// TimeoutMs is the overall deadline in milliseconds (default defaultSseTimeoutMs).
TimeoutMs int `json:"timeout_ms"`
// CompletionEvent, when set, stops the stream as soon as an event whose
// "event:" name OR raw data equals this value is dispatched.
CompletionEvent string `json:"completion_event"`
// StopOnAssertionFailure stops (and fails) the node on the first failing
// per-event assertion. Defaults to true.
StopOnAssertionFailure *bool `json:"stop_on_assertion_failure"`
}
SseData configures a connection to a text/event-stream endpoint that is consumed event-by-event over time.
type SseExecutionResult ¶
type SseExecutionResult struct {
spi.BaseExecutionResult
// RequestMethod and RequestURL capture the resolved connection details.
RequestMethod string `json:"request_method"`
RequestURL string `json:"request_url"`
// Events holds every dispatched event's parsed data (JSON when the data was
// valid JSON, otherwise the raw string), in arrival order.
Events []any `json:"events"`
// EventCount is len(Events).
EventCount int `json:"event_count"`
// StopReason records why streaming stopped (max_events, completion_event,
// timeout, eof, assertion_failure).
StopReason string `json:"stop_reason,omitempty"`
// Timing
DurationMs int64 `json:"duration_ms"`
}
SseExecutionResult stores SSE (Server-Sent Events) node execution data.
type SseNode ¶
type SseNode struct {
BaseNode
Data SseData `json:"data"`
// contains filtered or unexported fields
}
SseNode connects to a Server-Sent Events endpoint, consumes events over time, and runs the node's assertions against each event's parsed data with a cross-event accumulator. Unlike the buffered single-shot request node, it streams: events are processed as they arrive and the connection is closed as soon as a stop condition (max_events, completion_event, timeout, assertion failure, or EOF) is met.
func AsSseNode ¶
AsSseNode safely casts an AnyNode to an SseNode. Returns the SseNode and true if the cast succeeds, nil and false otherwise.
func (*SseNode) Execute ¶
Execute connects to the SSE endpoint and consumes events until a stop condition is met. On any failure it returns a populated result plus the error so the engine records a failed node.
func (*SseNode) InputSchema ¶
InputSchema infers inputs from template variables in URL and Headers.
func (*SseNode) OutputSchema ¶
OutputSchema returns the keys this node always produces.
type TemplateResolver ¶
type TemplateResolver struct {
// contains filtered or unexported fields
}
TemplateResolver handles resolution of {{variableName}} templates in strings and objects.
func NewTemplateResolver ¶
func NewTemplateResolver(variables map[string]any) *TemplateResolver
NewTemplateResolver creates a new template resolver with the given variables.
func NewTemplateResolverWithDynamics ¶
func NewTemplateResolverWithDynamics( variables map[string]any, dynamic spi.DynamicResolver, ) *TemplateResolver
NewTemplateResolverWithDynamics creates a resolver that also resolves {{$name}} dynamic variables via the given resolver (may be nil).
Source Files
¶
- assert_node.go
- assertion.go
- assertion_eval.go
- base.go
- branch_node.go
- builder.go
- consts.go
- delay_node.go
- loop_node.go
- module_node.go
- output.go
- output_view.go
- poll_node.go
- registry.go
- request_error.go
- request_execution.go
- request_node.go
- schema_inference.go
- set_variable_node.go
- sse_node.go
- template_resolver.go
- types.go
- unmarshal.go