Documentation
¶
Index ¶
- Constants
- func ExpandEnv(s string) string
- func NewApiCrawler(configPath string) (*ApiCrawler, []ValidationError, error)
- func NormalizeRawQuery(raw string) string
- func NormalizeURL(rawURL string) string
- func QueryParamEncode(value string) string
- func SetQueryParams(u *url.URL, params map[string]string)
- func ValidateAndCompile(cfg Config) (*CompiledConfig, []ValidationError, error)
- type ApiCrawler
- func (a *ApiCrawler) EnableProfiler() chan StepProfilerData
- func (c *ApiCrawler) ExecuteStep(ctx context.Context, exec *stepExecution) error
- func (a *ApiCrawler) GetData() interface{}
- func (a *ApiCrawler) GetDataStream() chan interface{}
- func (c *ApiCrawler) Run(ctx context.Context, vars map[string]any) error
- func (a *ApiCrawler) SetClient(client HTTPClient)
- func (a *ApiCrawler) SetLogger(logger Logger)
- type AuthProfiler
- type Authenticator
- type AuthenticatorConfig
- type BaseAuthenticator
- type BasicAuthenticator
- type BearerAuthenticator
- type CompiledBodyTemplates
- type CompiledBodyValue
- type CompiledConfig
- type CompiledJQ
- type CompiledMerge
- type CompiledStep
- func (cs *CompiledStep) ExecuteBodyTemplates(ctx map[string]any) (map[string]any, error)
- func (cs *CompiledStep) ExecuteHeaderTemplates(ctx map[string]any) (map[string]string, error)
- func (cs *CompiledStep) ExecutePathExtractor(data any) ([]interface{}, error)
- func (cs *CompiledStep) ExecuteResultTransformer(input any, templateCtx map[string]any) (any, error)
- func (cs *CompiledStep) ExecuteSyntheticMerge(contextData any, newValue any) (any, error)
- func (cs *CompiledStep) ExecuteURLTemplate(ctx map[string]any, defaultUrl string) (string, error)
- type CompiledTemplate
- type Config
- type ConfigP
- type Context
- type ContextData
- type CookieAuthenticator
- type CustomAuthenticator
- type HTTPClient
- type JWTAuthenticator
- type Logger
- type MergeEventData
- type MergeTarget
- type MergeWithContextRule
- type NoopAuthenticator
- type OAuthAuthenticator
- type OAuthConfig
- type Pagination
- type PaginationContext
- type PaginationEvalData
- type Paginator
- type ParallelismConfig
- type ParallelismSetupData
- type Param
- type ProfileEventType
- type Profiler
- func (p *Profiler) Channel() chan StepProfilerData
- func (p *Profiler) EmitContextMerge(pageID string, step Step, data MergeEventData)
- func (p *Profiler) EmitContextSelection(parentID string, step Step, contextKey string, contextMap map[string]*Context)
- func (p *Profiler) EmitContextSelectionWithWorker(parentID string, step Step, contextKey string, contextMap map[string]*Context, ...)
- func (p *Profiler) EmitError(name string, parentID string, err string)
- func (p *Profiler) EmitFinalResult(rootID string, result any)
- func (p *Profiler) EmitForEachStepEnd(stepID string, parentID string, step Step, startTime time.Time)
- func (p *Profiler) EmitForEachStepStart(step Step, parentID string) string
- func (p *Profiler) EmitForValuesStepEnd(stepID string, parentID string, step Step, startTime time.Time)
- func (p *Profiler) EmitForValuesStepStart(step Step, parentID string) string
- func (p *Profiler) EmitItemSelection(parentID string, step Step, index int, item any, contextKey string, ...) string
- func (p *Profiler) EmitItemSelectionWithWorker(parentID string, step Step, index int, item any, contextKey string, ...) string
- func (p *Profiler) EmitPaginationEval(pageID string, step Step, data PaginationEvalData)
- func (p *Profiler) EmitParallelismSetup(parentID string, step Step, data ParallelismSetupData)
- func (p *Profiler) EmitRequestDetails(pageID string, step Step, data RequestDetailsData)
- func (p *Profiler) EmitRequestPageEnd(pageID string, stepID string, step Step, pageNum int, startTime time.Time)
- func (p *Profiler) EmitRequestPageStart(stepID string, step Step, pageNum int) string
- func (p *Profiler) EmitRequestResponse(pageID string, step Step, data ResponseData)
- func (p *Profiler) EmitRequestStepEnd(stepID string, parentID string, step Step, startTime time.Time)
- func (p *Profiler) EmitRequestStepStart(step Step, parentID string) string
- func (p *Profiler) EmitResponseTransform(pageID string, step Step, rule string, before any, after any)
- func (p *Profiler) EmitRootStart(config Config, contextMap map[string]*Context) string
- func (p *Profiler) EmitStreamResult(parentID string, step Step, entity any, index int)
- func (p *Profiler) EmitURLComposition(pageID string, step Step, data URLCompositionData)
- func (p *Profiler) EmitValueSelection(parentID string, step Step, index int, value any, contextKey string) string
- func (p *Profiler) Enabled() bool
- type RequestConfig
- type RequestDetailsData
- type RequestParts
- type ResponseData
- type Step
- type StepNode
- type StepProfilerData
- type StepTopology
- func (t *StepTopology) GetNode(path string) *StepNode
- func (t *StepTopology) GetParallelBranches() []*StepNode
- func (t *StepTopology) GetStreamingPoints() []*StepNode
- func (t *StepTopology) String() string
- func (t *StepTopology) WalkPostOrder(fn func(*StepNode) bool)
- func (t *StepTopology) WalkPreOrder(fn func(*StepNode) bool)
- type StopCondition
- type URLCompositionData
- type ValidationError
Constants ¶
const JQ_CTX_KEY = "$ctx"
const JQ_RES_KEY = "$res"
Variables ¶
This section is empty.
Functions ¶
func ExpandEnv ¶ added in v1.0.9
ExpandEnv expands environment variables in a string. Supports ${VAR} and ${VAR:-default} syntax. If VAR is not set or empty:
- With default (${VAR:-default}): returns the default value
- Without default (${VAR}): returns empty string
func NewApiCrawler ¶
func NewApiCrawler(configPath string) (*ApiCrawler, []ValidationError, error)
func NormalizeRawQuery ¶ added in v1.0.7
NormalizeRawQuery percent-encodes characters that are invalid in a URL query string (spaces, '#', control characters, etc.) while preserving everything that is valid — including literal '+' signs and existing '%XX' sequences.
This operates directly on the raw query string WITHOUT a decode/re-encode round-trip, so '+' is never confused with space.
func NormalizeURL ¶ added in v1.0.7
NormalizeURL pre-encodes invalid characters in the query portion of a raw URL string, then parses it. This handles externally-sourced URLs (e.g., nextPageUrl from API responses) where query values may contain unencoded '#', '+', or spaces.
The key insight: url.Parse treats '#' as a fragment separator, silently dropping everything after it from the query. By running NormalizeRawQuery on the query portion BEFORE url.Parse, we encode '#' → '%23' so it is preserved.
Returns the original string unchanged if parsing fails.
func QueryParamEncode ¶ added in v1.0.7
QueryParamEncode percent-encodes a query parameter value per RFC 3986. Unlike url.QueryEscape (which uses application/x-www-form-urlencoded where space becomes '+'), this encodes space as '%20' and literal '+' as '%2B'.
func SetQueryParams ¶ added in v1.0.7
SetQueryParams appends query parameters to u using RFC 3986 encoding. Existing parameters in u.RawQuery are preserved exactly as-is — no decode/re-encode round-trip that would corrupt '+' signs.
func ValidateAndCompile ¶ added in v1.0.4
func ValidateAndCompile(cfg Config) (*CompiledConfig, []ValidationError, error)
ValidateAndCompile performs both structural validation and cold-start compilation. This is the preferred entry point for production use as it: 1. Validates the configuration structure 2. Pre-compiles all JQ expressions and templates (fail-fast) 3. Builds the execution topology
Returns the compiled config if successful, or validation errors if any step fails.
Types ¶
type ApiCrawler ¶
type ApiCrawler struct {
Config Config
CompiledConfig *CompiledConfig // Pre-compiled JQ/templates (nil for legacy mode)
ContextMap map[string]*Context
DataStream chan any
// contains filtered or unexported fields
}
func (*ApiCrawler) EnableProfiler ¶
func (a *ApiCrawler) EnableProfiler() chan StepProfilerData
func (*ApiCrawler) ExecuteStep ¶
func (c *ApiCrawler) ExecuteStep(ctx context.Context, exec *stepExecution) error
func (*ApiCrawler) GetData ¶
func (a *ApiCrawler) GetData() interface{}
func (*ApiCrawler) GetDataStream ¶
func (a *ApiCrawler) GetDataStream() chan interface{}
func (*ApiCrawler) SetClient ¶
func (a *ApiCrawler) SetClient(client HTTPClient)
func (*ApiCrawler) SetLogger ¶
func (a *ApiCrawler) SetLogger(logger Logger)
type AuthProfiler ¶
type AuthProfiler struct {
// contains filtered or unexported fields
}
AuthProfiler is a helper for emitting authentication profiling events
type Authenticator ¶
type Authenticator interface {
PrepareRequest(req *http.Request, requestID string) error
SetProfiler(profiler chan StepProfilerData)
}
func NewAuthenticator ¶
func NewAuthenticator(config AuthenticatorConfig, httpClient HTTPClient) Authenticator
NewAuthenticator creates an authenticator based on the configuration
type AuthenticatorConfig ¶
type AuthenticatorConfig struct {
Type string `yaml:"type,omitempty" json:"type,omitempty"` // basic | bearer | oauth | cookie | jwt | custom
// Basic auth
Username string `yaml:"username,omitempty" json:"username,omitempty"`
Password string `yaml:"password,omitempty" json:"password,omitempty"`
// Bearer auth
Token string `yaml:"token,omitempty" json:"token,omitempty"`
// OAuth (inlined for backward compatibility)
OAuthConfig `yaml:",inline" json:",inline"`
// Cookie/JWT/Custom auth
LoginRequest *RequestConfig `yaml:"loginRequest,omitempty" json:"loginRequest,omitempty"`
ExtractFrom string `yaml:"extractFrom,omitempty" json:"extractFrom,omitempty"` // cookie | header | body
ExtractSelector string `yaml:"extractSelector,omitempty" json:"extractSelector,omitempty"` // jq for body, name for cookie/header
InjectInto string `yaml:"injectInto,omitempty" json:"injectInto,omitempty"` // cookie | header | bearer | body | query
InjectKey string `yaml:"injectKey,omitempty" json:"injectKey,omitempty"` // name for cookie/header/query/body field
// Refresh settings
MaxAgeSeconds int `yaml:"maxAgeSeconds,omitempty" json:"maxAgeSeconds,omitempty"` // 0 = no refresh
}
type BaseAuthenticator ¶
type BaseAuthenticator struct {
// contains filtered or unexported fields
}
func (*BaseAuthenticator) GetProfiler ¶
func (a *BaseAuthenticator) GetProfiler() *AuthProfiler
func (*BaseAuthenticator) SetProfiler ¶
func (a *BaseAuthenticator) SetProfiler(profiler chan StepProfilerData)
type BasicAuthenticator ¶
type BasicAuthenticator struct {
*BaseAuthenticator
// contains filtered or unexported fields
}
BasicAuthenticator - HTTP Basic Authentication
func (*BasicAuthenticator) PrepareRequest ¶
func (a *BasicAuthenticator) PrepareRequest(req *http.Request, requestID string) error
type BearerAuthenticator ¶
type BearerAuthenticator struct {
*BaseAuthenticator
// contains filtered or unexported fields
}
BearerAuthenticator - Bearer token authentication
func (*BearerAuthenticator) PrepareRequest ¶
func (a *BearerAuthenticator) PrepareRequest(req *http.Request, requestID string) error
func (*BearerAuthenticator) SetProfiler ¶
func (a *BearerAuthenticator) SetProfiler(profiler chan StepProfilerData)
type CompiledBodyTemplates ¶ added in v1.0.4
type CompiledBodyTemplates struct {
Templates map[string]*CompiledBodyValue
}
CompiledBodyTemplates holds compiled templates for a request body. Structure mirrors the body map structure with templates replacing string values.
type CompiledBodyValue ¶ added in v1.0.4
type CompiledBodyValue struct {
// One of the following will be set:
StringTemplate *CompiledTemplate // For string values with templates
Literal any // For non-template values (numbers, bools, etc.)
Map map[string]*CompiledBodyValue // For nested objects
Array []*CompiledBodyValue // For arrays
}
CompiledBodyValue represents a body value that may contain templates. It mirrors the recursive structure of request bodies.
type CompiledConfig ¶ added in v1.0.4
type CompiledConfig struct {
Config Config // Original configuration
Steps map[string]*CompiledStep // Pre-compiled steps keyed by step path
Topology *StepTopology // Step execution topology
GlobalHeaderTemplates map[string]*CompiledTemplate // Pre-compiled global header templates
}
CompiledConfig holds the fully compiled configuration. This is the result of ValidateAndCompile and eliminates all runtime compilation.
func CompileConfig ¶ added in v1.0.4
func CompileConfig(cfg Config) (*CompiledConfig, error)
CompileConfig compiles all steps in a configuration. This is the main entry point for cold-start compilation.
func (*CompiledConfig) ExecuteGlobalHeaders ¶ added in v1.0.4
ExecuteGlobalHeaders renders all global header templates with the given context. Returns a map of header names to expanded values.
func (*CompiledConfig) GetCompiledStep ¶ added in v1.0.4
func (cc *CompiledConfig) GetCompiledStep(path string) *CompiledStep
GetCompiledStep retrieves a pre-compiled step by its path.
type CompiledJQ ¶ added in v1.0.4
type CompiledJQ struct {
Code *gojq.Code
Expression string // Original expression for error messages
Variables []string // Variable names (e.g., ["$res", "$ctx"])
UsedPaths []string // Paths referenced in the expression (for selective context)
}
CompiledJQ holds a pre-compiled JQ expression with its metadata. Created at validation time to enable fail-fast and avoid runtime mutex contention.
func (*CompiledJQ) Run ¶ added in v1.0.4
func (c *CompiledJQ) Run(input any, variables ...any) (any, error)
Run executes the compiled JQ expression against the input data.
func (*CompiledJQ) RunArray ¶ added in v1.0.4
func (c *CompiledJQ) RunArray(input any) ([]interface{}, error)
RunArray executes the JQ expression and returns results as an array. Handles jq expressions that emit items one-by-one or as arrays.
type CompiledMerge ¶ added in v1.0.4
type CompiledMerge struct {
Rule *CompiledJQ // The JQ expression to apply
Target MergeTarget // Which context to merge into
TargetName string // Context name (only for MergeTargetNamed)
SourceRule string // Original rule string for profiling
}
CompiledMerge holds a unified merge operation compiled from any of: - mergeOn (target: current) - mergeWithParentOn (target: parent) - mergeWithContext (target: named)
type CompiledStep ¶ added in v1.0.4
type CompiledStep struct {
StepPath string // Unique path to this step (e.g., "steps[0].steps[1]")
// Request step compilations
URLTemplate *CompiledTemplate // URL template
HeaderTemplates map[string]*CompiledTemplate // Header value templates
BodyTemplates *CompiledBodyTemplates // Body value templates
// Transform and merge compilations
ResultTransformer *CompiledJQ // Response transformation (.resultTransformer)
Merge *CompiledMerge // Unified merge (from mergeOn/mergeWithParentOn/mergeWithContext)
// ForEach compilations
PathExtractor *CompiledJQ // Path extraction for forEach (.path)
SyntheticMerge *CompiledJQ // Default forEach merge: path + " = $new"
// Nested steps (pre-compiled recursively)
NestedSteps []*CompiledStep
}
CompiledStep holds all pre-compiled expressions for a single step. This eliminates runtime compilation and its associated mutex contention.
func CompileStep ¶ added in v1.0.4
func CompileStep(step *Step, stepPath string) (*CompiledStep, []string, error)
CompileStep compiles all expressions in a step and its nested steps. stepPath is used for error messages and step lookup.
func (*CompiledStep) ExecuteBodyTemplates ¶ added in v1.0.4
ExecuteBodyTemplates expands all body templates with the given context.
func (*CompiledStep) ExecuteHeaderTemplates ¶ added in v1.0.4
ExecuteHeaderTemplates renders all header templates with the given context.
func (*CompiledStep) ExecutePathExtractor ¶ added in v1.0.4
func (cs *CompiledStep) ExecutePathExtractor(data any) ([]interface{}, error)
ExecutePathExtractor extracts items from context data for forEach iteration.
func (*CompiledStep) ExecuteResultTransformer ¶ added in v1.0.4
func (cs *CompiledStep) ExecuteResultTransformer(input any, templateCtx map[string]any) (any, error)
ExecuteResultTransformer transforms the response using the pre-compiled JQ expression.
func (*CompiledStep) ExecuteSyntheticMerge ¶ added in v1.0.4
func (cs *CompiledStep) ExecuteSyntheticMerge(contextData any, newValue any) (any, error)
ExecuteSyntheticMerge applies the default forEach merge (path = $new).
func (*CompiledStep) ExecuteURLTemplate ¶ added in v1.0.4
ExecuteURLTemplate renders the URL with the given context.
type CompiledTemplate ¶ added in v1.0.4
type CompiledTemplate struct {
Template *template.Template
Source string // Original template string for error messages
UsedFields []string // Fields referenced in the template (for selective context)
}
CompiledTemplate holds a pre-compiled Go template with its metadata. Created at validation time to enable fail-fast and avoid runtime mutex contention.
type Config ¶
type Config struct {
Steps []Step `yaml:"steps" json:"steps"`
RootContext interface{} `yaml:"rootContext" json:"rootContext"`
Authentication *AuthenticatorConfig `yaml:"auth,omitempty" json:"auth,omitempty"`
Headers map[string]string `yaml:"headers,omitempty" json:"headers,omitempty"`
Stream bool `yaml:"stream,omitempty" json:"stream,omitempty"`
}
type ConfigP ¶
type ConfigP struct {
Pagination Pagination `yaml:"pagination"`
}
type Context ¶
type Context struct {
Data interface{}
ParentContext string
// contains filtered or unexported fields
}
type ContextData ¶
type ContextData struct {
Data any `json:"data"`
ParentContext string `json:"parentContext"`
Depth int `json:"depth"`
Key string `json:"key"`
}
ContextData represents a single context in a snapshot
type CookieAuthenticator ¶
type CookieAuthenticator struct {
*BaseAuthenticator
// contains filtered or unexported fields
}
CookieAuthenticator - performs login via POST, extracts cookie, injects it
func (*CookieAuthenticator) PrepareRequest ¶
func (a *CookieAuthenticator) PrepareRequest(req *http.Request, requestID string) error
type CustomAuthenticator ¶
type CustomAuthenticator struct {
*BaseAuthenticator
// contains filtered or unexported fields
}
CustomAuthenticator - fully configurable authenticator
func (*CustomAuthenticator) PrepareRequest ¶
func (a *CustomAuthenticator) PrepareRequest(req *http.Request, requestID string) error
type JWTAuthenticator ¶
type JWTAuthenticator struct {
*BaseAuthenticator
// contains filtered or unexported fields
}
JWTAuthenticator - performs login via POST, extracts JWT from response
func (*JWTAuthenticator) PrepareRequest ¶
func (a *JWTAuthenticator) PrepareRequest(req *http.Request, requestID string) error
type Logger ¶
type Logger interface {
Debug(msg string, args ...any)
Info(msg string, args ...any)
Warning(msg string, args ...any)
Error(msg string, args ...any)
}
func NewDefaultLogger ¶
func NewDefaultLogger() Logger
func NewNoopLogger ¶
func NewNoopLogger() Logger
type MergeEventData ¶
type MergeEventData struct {
CurrentContextKey string
TargetContextKey string
MergeRule string
TargetContextBefore any
TargetContextAfter any
ContextMap map[string]*Context
}
MergeEventData holds data for context merge event
type MergeTarget ¶ added in v1.0.4
type MergeTarget int
MergeTarget indicates which context a merge operation should target.
const ( // MergeTargetCurrent merges into the current/working context MergeTargetCurrent MergeTarget = iota // MergeTargetParent merges into the parent context MergeTargetParent // MergeTargetNamed merges into a named context (specified by TargetName) MergeTargetNamed )
func (MergeTarget) String ¶ added in v1.0.4
func (t MergeTarget) String() string
String returns a human-readable name for the merge target.
type MergeWithContextRule ¶
type NoopAuthenticator ¶
type NoopAuthenticator struct {
*BaseAuthenticator
}
NoopAuthenticator - no authentication
func (NoopAuthenticator) PrepareRequest ¶
func (np NoopAuthenticator) PrepareRequest(req *http.Request, requestID string) error
type OAuthAuthenticator ¶
type OAuthAuthenticator struct {
*BaseAuthenticator
// contains filtered or unexported fields
}
OAuthAuthenticator - OAuth2 authentication
func (*OAuthAuthenticator) GetToken ¶
func (a *OAuthAuthenticator) GetToken(requestID string) (string, error)
GetToken retrieves a valid access token (refreshing if necessary)
func (*OAuthAuthenticator) GetTokenWithCache ¶
func (a *OAuthAuthenticator) GetTokenWithCache(requestID string) (string, bool, error)
GetTokenWithCache retrieves a valid access token and returns whether it was cached
func (*OAuthAuthenticator) PrepareRequest ¶
func (a *OAuthAuthenticator) PrepareRequest(req *http.Request, requestID string) error
type OAuthConfig ¶
type OAuthConfig struct {
Method string `yaml:"method,omitempty" json:"method,omitempty"` // password | client_credentials
TokenURL string `yaml:"tokenUrl,omitempty" json:"tokenUrl,omitempty"`
ClientID string `yaml:"clientId,omitempty" json:"clientId,omitempty"`
ClientSecret string `yaml:"clientSecret,omitempty" json:"clientSecret,omitempty"`
// usernam and password inherited from AuthenticatorConfig
Scopes []string `yaml:"scopes,omitempty" json:"scopes,omitempty"`
}
type Pagination ¶
type Pagination struct {
NextPageUrlSelector string `yaml:"nextPageUrlSelector,omitempty" json:"nextPageUrlSelector,omitempty"` // jq selector to get nextPage url
Params []Param `yaml:"params,omitempty" json:"params,omitempty"`
StopOn []StopCondition `yaml:"stopOn,omitempty" json:"stopOn,omitempty"`
}
type PaginationContext ¶
type PaginationContext map[string]interface{}
type PaginationEvalData ¶
type PaginationEvalData struct {
PageNumber int
PaginationConfig Pagination
PreviousResponseBody any
PreviousHeaders map[string]string
PreviousState map[string]any
AfterState map[string]any
}
PaginationEvalData holds data for pagination evaluation event
type Paginator ¶
type Paginator struct {
// contains filtered or unexported fields
}
func NewPaginator ¶
NewPaginator creates a new paginator from YAML config
func NewPaginatorFromFile ¶
NewPaginatorFromFile creates a new paginator from YAML config
func (*Paginator) Ctx ¶
func (p *Paginator) Ctx() PaginationContext
func (*Paginator) Next ¶
Next advances the paginator and returns query/body/header params for the next request
func (*Paginator) NextFromCtx ¶
func (p *Paginator) NextFromCtx() *RequestParts
type ParallelismConfig ¶
type ParallelismSetupData ¶
type ParallelismSetupData struct {
MaxConcurrency int
WorkerPoolID string
WorkerIDs []int
RateLimit float64
Burst int
}
ParallelismSetupData holds data for parallelism setup event
type Param ¶
type Param struct {
Name string `yaml:"name" json:"name"`
Location string `yaml:"location" json:"location"` // "query", "body", "header"
Type string `yaml:"type" json:"type"` // "int", "float", "datetime", "dynamic"`
Format string `yaml:"format,omitempty" json:"format,omitempty"`
Default string `yaml:"default" json:"default"`
Increment string `yaml:"increment,omitempty" json:"increment,omitempty"`
Source string `yaml:"source,omitempty" json:"source,omitempty"` // "body:selector" or "header:selector"
}
type ProfileEventType ¶
type ProfileEventType int
const ( // Root EVENT_ROOT_START ProfileEventType = iota // Request step container EVENT_REQUEST_STEP_START EVENT_REQUEST_STEP_END // Request step sub-events EVENT_CONTEXT_SELECTION EVENT_REQUEST_PAGE_START EVENT_REQUEST_PAGE_END EVENT_PAGINATION_EVAL EVENT_URL_COMPOSITION EVENT_REQUEST_DETAILS EVENT_REQUEST_RESPONSE EVENT_RESPONSE_TRANSFORM EVENT_CONTEXT_MERGE // ForEach step container EVENT_FOREACH_STEP_START EVENT_FOREACH_STEP_END // ForValues step container EVENT_FORVALUES_STEP_START EVENT_FORVALUES_STEP_END // ForEach/ForValues step sub-events EVENT_PARALLELISM_SETUP EVENT_ITEM_SELECTION // Authentication events EVENT_AUTH_START EVENT_AUTH_CACHED EVENT_AUTH_LOGIN_START EVENT_AUTH_LOGIN_END EVENT_AUTH_TOKEN_EXTRACT EVENT_AUTH_TOKEN_INJECT EVENT_AUTH_END // Result events EVENT_RESULT EVENT_STREAM_RESULT // Errors EVENT_ERROR )
type Profiler ¶
type Profiler struct {
// contains filtered or unexported fields
}
Profiler wraps the profiler channel and provides methods for emitting events. All methods are safe to call even when the profiler is disabled (nil channel).
func NewProfiler ¶
NewProfiler creates a new Profiler instance
func (*Profiler) Channel ¶
func (p *Profiler) Channel() chan StepProfilerData
Channel returns the underlying channel for consumers to read from
func (*Profiler) EmitContextMerge ¶
func (p *Profiler) EmitContextMerge(pageID string, step Step, data MergeEventData)
EmitContextMerge emits context merge event NOT THREAD SAFE
func (*Profiler) EmitContextSelection ¶
func (p *Profiler) EmitContextSelection(parentID string, step Step, contextKey string, contextMap map[string]*Context)
EmitContextSelection emits context selection event
func (*Profiler) EmitContextSelectionWithWorker ¶
func (p *Profiler) EmitContextSelectionWithWorker(parentID string, step Step, contextKey string, contextMap map[string]*Context, workerID int, workerPool string)
EmitContextSelectionWithWorker emits context selection event with worker tracking
func (*Profiler) EmitFinalResult ¶
EmitFinalResult emits the final result event (non-streaming mode)
func (*Profiler) EmitForEachStepEnd ¶
func (p *Profiler) EmitForEachStepEnd(stepID string, parentID string, step Step, startTime time.Time)
EmitForEachStepEnd emits forEach step end event
func (*Profiler) EmitForEachStepStart ¶
EmitForEachStepStart emits forEach step start and returns the step ID
func (*Profiler) EmitForValuesStepEnd ¶
func (p *Profiler) EmitForValuesStepEnd(stepID string, parentID string, step Step, startTime time.Time)
EmitForValuesStepEnd emits forValues step end event
func (*Profiler) EmitForValuesStepStart ¶
EmitForValuesStepStart emits forValues step start and returns the step ID
func (*Profiler) EmitItemSelection ¶
func (p *Profiler) EmitItemSelection(parentID string, step Step, index int, item any, contextKey string, contextData any) string
EmitItemSelection emits item selection event and returns the item ID
func (*Profiler) EmitItemSelectionWithWorker ¶
func (p *Profiler) EmitItemSelectionWithWorker(parentID string, step Step, index int, item any, contextKey string, contextData any, workerID int, workerPool string) string
EmitItemSelectionWithWorker emits item selection event with worker tracking
func (*Profiler) EmitPaginationEval ¶
func (p *Profiler) EmitPaginationEval(pageID string, step Step, data PaginationEvalData)
EmitPaginationEval emits pagination evaluation event
func (*Profiler) EmitParallelismSetup ¶
func (p *Profiler) EmitParallelismSetup(parentID string, step Step, data ParallelismSetupData)
EmitParallelismSetup emits parallelism setup event
func (*Profiler) EmitRequestDetails ¶
func (p *Profiler) EmitRequestDetails(pageID string, step Step, data RequestDetailsData)
EmitRequestDetails emits request details event
func (*Profiler) EmitRequestPageEnd ¶
func (p *Profiler) EmitRequestPageEnd(pageID string, stepID string, step Step, pageNum int, startTime time.Time)
EmitRequestPageEnd emits page end event
func (*Profiler) EmitRequestPageStart ¶
EmitRequestPageStart emits page start and returns the page ID
func (*Profiler) EmitRequestResponse ¶
func (p *Profiler) EmitRequestResponse(pageID string, step Step, data ResponseData)
EmitRequestResponse emits request response event
func (*Profiler) EmitRequestStepEnd ¶
func (p *Profiler) EmitRequestStepEnd(stepID string, parentID string, step Step, startTime time.Time)
EmitRequestStepEnd emits request step end event
func (*Profiler) EmitRequestStepStart ¶
EmitRequestStepStart emits request step start and returns the step ID
func (*Profiler) EmitResponseTransform ¶
func (p *Profiler) EmitResponseTransform(pageID string, step Step, rule string, before any, after any)
EmitResponseTransform emits response transform event
func (*Profiler) EmitRootStart ¶
EmitRootStart emits the root start event and returns the root ID
func (*Profiler) EmitStreamResult ¶
EmitStreamResult emits stream result event
func (*Profiler) EmitURLComposition ¶
func (p *Profiler) EmitURLComposition(pageID string, step Step, data URLCompositionData)
EmitURLComposition emits URL composition event
type RequestConfig ¶
type RequestConfig struct {
URL string `yaml:"url" json:"url"`
Method string `yaml:"method" json:"method"`
Headers map[string]string `yaml:"headers,omitempty" json:"headers,omitempty"`
Body map[string]any `yaml:"body,omitempty" json:"body,omitempty"`
Pagination Pagination `yaml:"pagination,omitempty" json:"pagination,omitempty"`
Authentication *AuthenticatorConfig `yaml:"auth,omitempty" json:"auth,omitempty"`
}
type RequestDetailsData ¶
type RequestDetailsData struct {
CurlCommand string
Method string
URL string
Headers map[string]string
Body map[string]interface{}
}
RequestDetailsData holds data for request details event
type RequestParts ¶
type ResponseData ¶
type ResponseData struct {
StatusCode int
Headers map[string]string
Body any
ResponseSize int
DurationMs int64
}
ResponseData holds data for response event
type Step ¶
type Step struct {
Type string `yaml:"type" json:"type"`
Name string `yaml:"name,omitempty" json:"name,omitempty"`
Path string `yaml:"path,omitempty" json:"path,omitempty"`
As string `yaml:"as,omitempty" json:"as,omitempty"`
Values []interface{} `yaml:"values,omitempty" json:"values,omitempty"`
Steps []Step `yaml:"steps,omitempty" json:"steps,omitempty"`
Request *RequestConfig `yaml:"request,omitempty" json:"request,omitempty"`
ResultTransformer string `yaml:"resultTransformer,omitempty" json:"resultTransformer,omitempty"`
MergeWithParentOn string `yaml:"mergeWithParentOn,omitempty" json:"mergeWithParentOn,omitempty"`
MergeOn string `yaml:"mergeOn,omitempty" json:"mergeOn,omitempty"`
MergeWithContext *MergeWithContextRule `yaml:"mergeWithContext,omitempty" json:"mergeWithContext,omitempty"`
NoopMerge bool `yaml:"noopMerge,omitempty" json:"noopMerge,omitempty"`
Parallelism *ParallelismConfig `yaml:"parallelism,omitempty" json:"parallelism,omitempty"`
}
type StepNode ¶ added in v1.0.4
type StepNode struct {
StepPath string // Unique path (e.g., "steps[0].steps[1]")
StepRef *Step // Reference to the original step definition
Parent *StepNode
Children []*StepNode
Depth int // Distance from root (0 = top-level step)
// Execution characteristics
IsParallel bool // forEach with parallelism config
IsForEach bool // forEach or forValues step
HasMerge bool // Step has explicit merge rule
// Streaming characteristics
MergesToRoot bool // Merge target is root or depth <= 1 (triggers streaming)
MergeTarget string // Context name that this step merges to
}
StepNode represents a step in the execution topology tree. Used for planning execution order, determining parallelism, and identifying when to emit streamed results.
func (*StepNode) GetMergeTargetNode ¶ added in v1.0.4
func (n *StepNode) GetMergeTargetNode(topology *StepTopology) *StepNode
GetMergeTargetNode returns the node that this step merges to.
func (*StepNode) IsStreamingPoint ¶ added in v1.0.4
IsStreamingPoint returns true if this step should trigger streaming when it completes (merges to root at depth <= 1).
type StepProfilerData ¶
type StepProfilerData struct {
// Core identification
ID string `json:"id"`
ParentID string `json:"parentId,omitempty"`
Type ProfileEventType `json:"type"`
Name string `json:"name"`
Step Step `json:"step"`
// Timeline
Timestamp time.Time `json:"timestamp"`
Duration int64 `json:"durationMs,omitempty"` // Only in END events
// Worker tracking (for parallel execution)
WorkerID int `json:"workerId,omitempty"`
WorkerPool string `json:"workerPool,omitempty"`
// Flexible event-specific data
Data map[string]any `json:"data"`
}
type StepTopology ¶ added in v1.0.4
type StepTopology struct {
// Root nodes (top-level steps)
Roots []*StepNode
// All nodes indexed by path for O(1) lookup
ByPath map[string]*StepNode
// Statistics
MaxDepth int
TotalSteps int
ParallelSteps int
}
StepTopology holds the complete step execution topology. Built at validation time from the configuration.
func BuildTopology ¶ added in v1.0.4
func BuildTopology(cfg Config) *StepTopology
BuildTopology constructs the step execution topology from a configuration. This analyzes the step hierarchy and determines execution characteristics.
func (*StepTopology) GetNode ¶ added in v1.0.4
func (t *StepTopology) GetNode(path string) *StepNode
GetNode retrieves a step node by its path.
func (*StepTopology) GetParallelBranches ¶ added in v1.0.4
func (t *StepTopology) GetParallelBranches() []*StepNode
GetParallelBranches returns all nodes that execute in parallel.
func (*StepTopology) GetStreamingPoints ¶ added in v1.0.4
func (t *StepTopology) GetStreamingPoints() []*StepNode
GetStreamingPoints returns all nodes that should trigger streaming.
func (*StepTopology) String ¶ added in v1.0.4
func (t *StepTopology) String() string
String returns a human-readable representation of the topology.
func (*StepTopology) WalkPostOrder ¶ added in v1.0.4
func (t *StepTopology) WalkPostOrder(fn func(*StepNode) bool)
WalkPostOrder visits all nodes in post-order (children before parent).
func (*StepTopology) WalkPreOrder ¶ added in v1.0.4
func (t *StepTopology) WalkPreOrder(fn func(*StepNode) bool)
WalkPreOrder visits all nodes in pre-order (parent before children).
type StopCondition ¶
type StopCondition struct {
Type string `yaml:"type" json:"type"` // "responseBody", "requestParam", "pageNum"
Expression string `yaml:"expression" json:"expression"` // used by jq
Param string `yaml:"param,omitempty" json:"param,omitempty"` // for requestParam
Compare string `yaml:"compare,omitempty" json:"compare,omitempty"` // "lt", "lte", "eq", "gt", "gte"
Value any `yaml:"value,omitempty" json:"value,omitempty"` // value to compare against
}
type URLCompositionData ¶
type URLCompositionData struct {
URLTemplate string
PageNumber int
QueryParams map[string]string
BodyParams map[string]interface{}
NextPageURL string
TemplateContext map[string]any
ResultURL string
ResultHeaders map[string]string
ResultBody interface{}
}
URLCompositionData holds data for URL composition event
type ValidationError ¶
type ValidationError struct {
Message string
Location string // optional, e.g. "steps[0].request.url"
}
func ValidateConfig ¶
func ValidateConfig(cfg Config) []ValidationError
func (ValidationError) Error ¶
func (e ValidationError) Error() string
