| 524 | } |
| 525 | |
| 526 | function maskSecretOutputs(outputPorts: ComponentPortMetadata[], output: unknown): unknown { |
| 527 | const secretPorts = |
| 528 | outputPorts.filter((port) => { |
| 529 | const connectionType = port.connectionType; |
| 530 | |
| 531 | if (connectionType.kind === 'primitive') { |
| 532 | return connectionType.name === 'secret'; |
| 533 | } |
| 534 | if (connectionType.kind === 'contract') { |
| 535 | return Boolean(connectionType.credential); |
| 536 | } |
| 537 | return false; |
| 538 | }) ?? []; |
| 539 | if (secretPorts.length === 0) { |
| 540 | return output; |
| 541 | } |
| 542 | |
| 543 | if (secretPorts.some((port) => port.id === '__self__')) { |
| 544 | return '***'; |
| 545 | } |
| 546 | |
| 547 | if (output && typeof output === 'object' && !Array.isArray(output)) { |
| 548 | const clone = { ...(output as Record<string, unknown>) }; |
| 549 | for (const port of secretPorts) { |
| 550 | if (Object.prototype.hasOwnProperty.call(clone, port.id)) { |
| 551 | clone[port.id] = '***'; |
| 552 | } |
| 553 | } |
| 554 | return clone; |
| 555 | } |
| 556 | |
| 557 | return '***'; |
| 558 | } |