(value: any)
| 257 | const types = 'inputs' |
| 258 | |
| 259 | const resolveNodeReference = async (value: any): Promise<any> => { |
| 260 | // If value is an array, process each element |
| 261 | if (Array.isArray(value)) { |
| 262 | return Promise.all(value.map((item) => resolveNodeReference(item))) |
| 263 | } |
| 264 | |
| 265 | // If value is an object, process each property |
| 266 | if (typeof value === 'object' && value !== null) { |
| 267 | const resolvedObj: any = {} |
| 268 | for (const [key, val] of Object.entries(value)) { |
| 269 | resolvedObj[key] = await resolveNodeReference(val) |
| 270 | } |
| 271 | return resolvedObj |
| 272 | } |
| 273 | |
| 274 | // If value is not a string, return as is |
| 275 | if (typeof value !== 'string') return value |
| 276 | |
| 277 | // Convert legacy HTML content to markdown, preserving any markdown syntax within. |
| 278 | // Legacy content from old getHTML() starts with a TipTap block tag (e.g. <p>text</p>). |
| 279 | // Anchor with ^ to avoid matching intentional HTML/XML tags in user prompts |
| 280 | // (e.g. <instruction><div>...</div></instruction>). |
| 281 | if (/^\s*<(?:p|div|h[1-6]|ul|ol|blockquote|pre|table)\b/i.test(value)) { |
| 282 | const turndownService = new TurndownService() |
| 283 | // Disable escaping so markdown characters (e.g. ###, -, *) inside HTML are preserved as-is |
| 284 | turndownService.escape = (str: string) => str |
| 285 | value = turndownService.turndown(value) |
| 286 | } |
| 287 | |
| 288 | const matches = value.match(/{{(.*?)}}/g) |
| 289 | |
| 290 | if (!matches) return value |
| 291 | |
| 292 | let resolvedValue = value |
| 293 | for (const match of matches) { |
| 294 | // Remove {{ }} and trim whitespace |
| 295 | const reference = match.replace(/[{}]/g, '').trim() |
| 296 | const variableFullPath = reference |
| 297 | |
| 298 | if (variableFullPath === QUESTION_VAR_PREFIX) { |
| 299 | resolvedValue = resolvedValue.replace(match, question) |
| 300 | resolvedValue = uploadedFilesContent ? `${uploadedFilesContent}\n\n${resolvedValue}` : resolvedValue |
| 301 | } |
| 302 | |
| 303 | if (variableFullPath.startsWith('$form.')) { |
| 304 | const variableValue = get(form, variableFullPath.replace('$form.', '')) |
| 305 | if (variableValue != null) { |
| 306 | // For arrays and objects, stringify them to prevent toString() conversion issues |
| 307 | const formattedValue = |
| 308 | Array.isArray(variableValue) || (typeof variableValue === 'object' && variableValue !== null) |
| 309 | ? JSON.stringify(variableValue) |
| 310 | : variableValue |
| 311 | resolvedValue = resolvedValue.replace(match, formattedValue) |
| 312 | } |
| 313 | } |
| 314 | |
| 315 | if (variableFullPath.startsWith('$webhook.')) { |
| 316 | const variableValue = get(webhook, variableFullPath.replace('$webhook.', '')) |
no test coverage detected