fix(external-triggers): not passing payload through + incorrect server-side resolver logic (#1801)

* fix integration triggers

* ignore text readonly subblocks

* fix

* fix to ignore readOnly vals

* fix var references

* simplify

* cleanup code
This commit is contained in:
Vikhyath Mondreti
2025-11-03 19:54:42 -08:00
committed by GitHub
parent d1fcade5ab
commit 0363f8a33d
4 changed files with 59 additions and 64 deletions

View File

@@ -76,7 +76,13 @@ export function buildResolutionFromBlock(block: SerializedBlock): ExecutorStartR
return null
}
const path = classifyStartBlockType(type)
const category = block.metadata?.category
const triggerModeEnabled = block.config?.params?.triggerMode === true
const path = classifyStartBlockType(type, {
category,
triggerModeEnabled,
})
if (!path) {
return null
}
@@ -342,11 +348,11 @@ function buildManualTriggerOutput(
finalInput: unknown,
workflowInput: unknown
): NormalizedBlockOutput {
const finalObject = isPlainObject(finalInput) ? finalInput : undefined
const finalObject = isPlainObject(finalInput)
? (finalInput as Record<string, unknown>)
: undefined
const output: NormalizedBlockOutput = finalObject
? { ...(finalObject as Record<string, unknown>) }
: { input: finalInput }
const output: NormalizedBlockOutput = finalObject ? { ...finalObject } : { input: finalInput }
if (!Object.hasOwn(output, 'input')) {
output.input = getRawInputCandidate(workflowInput)
@@ -355,6 +361,24 @@ function buildManualTriggerOutput(
return mergeFilesIntoOutput(output, workflowInput)
}
function buildIntegrationTriggerOutput(
finalInput: unknown,
workflowInput: unknown
): NormalizedBlockOutput {
const base: NormalizedBlockOutput = isPlainObject(workflowInput)
? ({ ...(workflowInput as Record<string, unknown>) } as NormalizedBlockOutput)
: {}
if (isPlainObject(finalInput)) {
Object.assign(base, finalInput as Record<string, unknown>)
base.input = { ...(finalInput as Record<string, unknown>) }
} else {
base.input = finalInput
}
return mergeFilesIntoOutput(base, workflowInput)
}
function extractSubBlocks(block: SerializedBlock): Record<string, unknown> | undefined {
const metadata = block.metadata
if (!metadata || typeof metadata !== 'object') {
@@ -398,6 +422,9 @@ export function buildStartBlockOutput(options: StartBlockOutputOptions): Normali
case StartBlockPath.SPLIT_MANUAL:
return buildManualTriggerOutput(finalInput, workflowInput)
case StartBlockPath.EXTERNAL_TRIGGER:
return buildIntegrationTriggerOutput(finalInput, workflowInput)
case StartBlockPath.LEGACY_STARTER:
return buildLegacyStarterOutput(
finalInput,

View File

@@ -12,53 +12,6 @@ import { WorkflowResolver } from './resolvers/workflow'
const logger = createLogger('VariableResolver')
const INVALID_REFERENCE_CHARS = /[+*/=<>!]/
function isLikelyReferenceSegment(segment: string): boolean {
if (!segment.startsWith(REFERENCE.START) || !segment.endsWith(REFERENCE.END)) {
return false
}
const inner = segment.slice(1, -1)
// Starts with space - not a reference
if (inner.startsWith(' ')) {
return false
}
// Contains only comparison operators or has operators with spaces
if (inner.match(/^\s*[<>=!]+\s*$/) || inner.match(/\s[<>=!]+\s/)) {
return false
}
// Starts with comparison operator followed by space
if (inner.match(/^[<>=!]+\s/)) {
return false
}
// For dotted references (like <block.field>)
if (inner.includes('.')) {
const dotIndex = inner.indexOf('.')
const beforeDot = inner.substring(0, dotIndex)
const afterDot = inner.substring(dotIndex + 1)
// No spaces after dot
if (afterDot.includes(' ')) {
return false
}
// No invalid chars in either part
if (INVALID_REFERENCE_CHARS.test(beforeDot) || INVALID_REFERENCE_CHARS.test(afterDot)) {
return false
}
} else if (INVALID_REFERENCE_CHARS.test(inner) || inner.match(/^\d/) || inner.match(/\s\d/)) {
// No invalid chars, doesn't start with digit, no space before digit
return false
}
return true
}
export class VariableResolver {
private resolvers: Resolver[]
private blockResolver: BlockResolver
@@ -197,10 +150,6 @@ export class VariableResolver {
result = result.replace(referenceRegex, (match) => {
if (replacementError) return match
if (!isLikelyReferenceSegment(match)) {
return match
}
try {
const resolved = this.resolveReference(match, resolutionContext)
if (resolved === undefined) {
@@ -260,10 +209,6 @@ export class VariableResolver {
result = result.replace(referenceRegex, (match) => {
if (replacementError) return match
if (!isLikelyReferenceSegment(match)) {
return match
}
try {
const resolved = this.resolveReference(match, resolutionContext)
if (resolved === undefined) {

View File

@@ -46,8 +46,8 @@ export class BlockResolver implements Resolver {
const blockId = this.findBlockIdByName(blockName)
if (!blockId) {
logger.error('Block not found by name', { blockName, reference })
throw new Error(`Block "${blockName}" not found`)
logger.debug('Block not found by name, skipping resolution', { blockName, reference })
return undefined
}
const output = this.getBlockOutput(blockId, context)