( blocks: Iterable<FlattenOutputsBlockInput>, edges: Iterable<FlattenOutputsEdgeInput> = [] )
| 54 | * appear first. This matches the deploy modal's grouping order. |
| 55 | */ |
| 56 | export function flattenWorkflowOutputs( |
| 57 | blocks: Iterable<FlattenOutputsBlockInput>, |
| 58 | edges: Iterable<FlattenOutputsEdgeInput> = [] |
| 59 | ): FlattenedBlockOutput[] { |
| 60 | const blockList = Array.from(blocks) |
| 61 | const results: FlattenedBlockOutput[] = [] |
| 62 | |
| 63 | for (const block of blockList) { |
| 64 | if (!block?.id || !block?.type) continue |
| 65 | if (EXCLUDED_OUTPUT_TYPES.has(block.type)) continue |
| 66 | |
| 67 | const normalizedSubBlocks: Record<string, { value: unknown }> = {} |
| 68 | if (block.subBlocks && typeof block.subBlocks === 'object') { |
| 69 | for (const [k, v] of Object.entries(block.subBlocks)) { |
| 70 | normalizedSubBlocks[k] = |
| 71 | v && typeof v === 'object' && 'value' in (v as object) |
| 72 | ? (v as { value: unknown }) |
| 73 | : { value: v } |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | const effectiveTriggerMode = Boolean(block.triggerMode) |
| 78 | let outs: Record<string, unknown> = {} |
| 79 | try { |
| 80 | outs = getEffectiveBlockOutputs(block.type, normalizedSubBlocks, { |
| 81 | triggerMode: effectiveTriggerMode, |
| 82 | preferToolOutputs: !effectiveTriggerMode, |
| 83 | }) as Record<string, unknown> |
| 84 | } catch { |
| 85 | continue |
| 86 | } |
| 87 | if (!outs || Object.keys(outs).length === 0) continue |
| 88 | |
| 89 | const blockName = block.name || `Block ${block.id}` |
| 90 | const add = (path: string, outputObj: unknown, prefix = ''): void => { |
| 91 | const fullPath = prefix ? `${prefix}.${path}` : path |
| 92 | const declaredType = |
| 93 | outputObj && |
| 94 | typeof outputObj === 'object' && |
| 95 | !Array.isArray(outputObj) && |
| 96 | 'type' in (outputObj as object) && |
| 97 | typeof (outputObj as { type: unknown }).type === 'string' |
| 98 | ? (outputObj as { type: string }).type |
| 99 | : undefined |
| 100 | const isLeaf = |
| 101 | typeof outputObj !== 'object' || |
| 102 | outputObj === null || |
| 103 | declaredType !== undefined || |
| 104 | Array.isArray(outputObj) |
| 105 | if (isLeaf) { |
| 106 | results.push({ |
| 107 | blockId: block.id, |
| 108 | blockName, |
| 109 | blockType: block.type, |
| 110 | path: fullPath, |
| 111 | leafType: declaredType, |
| 112 | }) |
| 113 | return |
no test coverage detected