mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-06 03:00:16 -04:00
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:
committed by
GitHub
parent
d1fcade5ab
commit
0363f8a33d
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -23,6 +23,7 @@ export enum StartBlockPath {
|
||||
SPLIT_API = 'legacy_api_trigger',
|
||||
SPLIT_CHAT = 'legacy_chat_trigger',
|
||||
SPLIT_MANUAL = 'legacy_manual_trigger',
|
||||
EXTERNAL_TRIGGER = 'external_trigger',
|
||||
}
|
||||
|
||||
type StartExecutionKind = 'chat' | 'manual' | 'api'
|
||||
@@ -60,13 +61,26 @@ const START_CONFLICT_TYPES: TriggerType[] = [
|
||||
|
||||
type BlockWithType = { type: string; subBlocks?: Record<string, unknown> | undefined }
|
||||
|
||||
type BlockWithMetadata = BlockWithType & {
|
||||
category?: string
|
||||
triggers?: { enabled?: boolean }
|
||||
}
|
||||
|
||||
export interface StartBlockCandidate<T extends BlockWithType> {
|
||||
blockId: string
|
||||
block: T
|
||||
path: StartBlockPath
|
||||
}
|
||||
|
||||
export function classifyStartBlockType(type: string): StartBlockPath | null {
|
||||
type ClassifyStartOptions = {
|
||||
category?: string
|
||||
triggerModeEnabled?: boolean
|
||||
}
|
||||
|
||||
export function classifyStartBlockType(
|
||||
type: string,
|
||||
opts?: ClassifyStartOptions
|
||||
): StartBlockPath | null {
|
||||
switch (type) {
|
||||
case TRIGGER_TYPES.START:
|
||||
return StartBlockPath.UNIFIED
|
||||
@@ -80,13 +94,22 @@ export function classifyStartBlockType(type: string): StartBlockPath | null {
|
||||
return StartBlockPath.SPLIT_CHAT
|
||||
case TRIGGER_TYPES.MANUAL:
|
||||
return StartBlockPath.SPLIT_MANUAL
|
||||
case TRIGGER_TYPES.WEBHOOK:
|
||||
case TRIGGER_TYPES.SCHEDULE:
|
||||
return StartBlockPath.EXTERNAL_TRIGGER
|
||||
default:
|
||||
if (opts?.category === 'triggers' || opts?.triggerModeEnabled) {
|
||||
return StartBlockPath.EXTERNAL_TRIGGER
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function classifyStartBlock<T extends BlockWithType>(block: T): StartBlockPath | null {
|
||||
return classifyStartBlockType(block.type)
|
||||
const blockWithMetadata = block as BlockWithMetadata
|
||||
const category = blockWithMetadata.category
|
||||
const triggerModeEnabled = Boolean(blockWithMetadata.triggers?.enabled)
|
||||
return classifyStartBlockType(block.type, { category, triggerModeEnabled })
|
||||
}
|
||||
|
||||
export function isLegacyStartPath(path: StartBlockPath): boolean {
|
||||
|
||||
Reference in New Issue
Block a user