{ "kind": "open-flow-workflow", "version": 1, "name": "Output Completion Check", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_dd5e606433693a6c": { "name": "Completed records", "kind": "start", "inputDefs": [ { "jsonSchema": { "type": "array", "items": { "type": "object" } }, "nullable": false, "handle": "records" } ] }, "n_e03d4ad377427338": { "inputs": { "records": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_dd5e606433693a6c", "output": "records" } ] }, "minimumItems": { "kind": "value", "value": 1 }, "recordIdField": { "kind": "value", "value": "recordId" } }, "name": "Check completed outputs", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object" } }, "nullable": false, "handle": "records" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "minimumItems" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "recordIdField" } ], "outputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "checkPassed" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "checkStatus" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "minimumItems" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "items" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "invalidItems" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "duplicateItems" } ], "name": "Check completed outputs", "moduleId": "n_eaa2a0816ba8b708", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_9a785b02617eb938": { "name": "Completion report", "kind": "outputs", "outputDefs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "checkPassed" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "checkStatus" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "minimumItems" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "items" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "invalidItems" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "duplicateItems" } ], "outputMappings": { "checkPassed": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_e03d4ad377427338", "output": "checkPassed" } ] }, "checkStatus": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_e03d4ad377427338", "output": "checkStatus" } ] }, "minimumItems": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_e03d4ad377427338", "output": "minimumItems" } ] }, "items": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_e03d4ad377427338", "output": "items" } ] }, "invalidItems": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_e03d4ad377427338", "output": "invalidItems" } ] }, "duplicateItems": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_e03d4ad377427338", "output": "duplicateItems" } ] } } } }, "edges": [ { "source": "n_dd5e606433693a6c", "target": "n_e03d4ad377427338" }, { "source": "n_e03d4ad377427338", "target": "n_9a785b02617eb938" } ] } }, "modules": { "n_eaa2a0816ba8b708": { "name": "Check completed outputs", "imports": [], "source": "export default function checkOutputs({records,minimumItems,recordIdField}) {\n const minimum=Number(minimumItems);\n if(!Number.isSafeInteger(minimum)||minimum<0||minimum>1000000000)throw new Error('minimumItems must be a non-negative integer, at most 1000000000.');\n const field=String(recordIdField||'').trim();\n if(!field)throw new Error('Set recordIdField to the field identifying a completed output.');\n if(!Array.isArray(records)||records.some(record=>!record||typeof record!=='object'||Array.isArray(record)))throw new Error('records must be an array of objects.');\n const rows=records.filter(record=>Object.keys(record).length>0);\n const keys=new Set();let invalidItems=0;\n for(const row of rows){\n const value=row[field];\n const valid=(typeof value==='string'&&value.trim().length>0)||(typeof value==='number'&&Number.isFinite(value));\n if(!valid){invalidItems++;continue;}\n keys.add(String(value).trim());\n }\n const items=keys.size;\n const duplicateItems=rows.length-invalidItems-items;\n return {checkPassed:items>=minimum&&invalidItems===0,checkStatus:invalidItems?'invalid_output':items