{ "kind": "open-flow-workflow", "version": 1, "name": "Hacker News Popular Items", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_aef8eeb45f19a46c": { "name": "Export Hacker News items", "kind": "start", "inputDefs": [] }, "n_c99ec8f01da71301": { "inputs": { "endpoint": { "kind": "value", "value": "/search" }, "query.hitsPerPage": { "kind": "value", "value": 50 }, "query.tags": { "kind": "value", "value": "" } }, "name": "Read popular items", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "endpoint" }, { "jsonSchema": { "type": [ "string", "number", "boolean", "null" ] }, "nullable": true, "handle": "query.hitsPerPage" }, { "jsonSchema": { "type": [ "string", "number", "boolean", "null" ] }, "nullable": true, "handle": "query.tags" } ], "outputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "type": "object", "additionalProperties": { "type": "string" } }, "nullable": false, "handle": "headers" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" } ], "name": "Read popular items", "executor": { "providerId": "hackernews", "method": "GET", "query": { "mode": "fields", "names": [ "hitsPerPage", "tags" ] }, "headers": { "mode": "fields", "names": [] }, "bodyFormat": "none", "kind": "connector-proxy" } } }, "n_27895fb05fec3105": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_c99ec8f01da71301", "output": "body" } ] }, "statusCode": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_c99ec8f01da71301", "output": "statusCode" } ] }, "bodyEncoding": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_c99ec8f01da71301", "output": "bodyEncoding" } ] } }, "name": "Build JSON snapshot", "kind": "task", "task": { "inputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "response" }, { "jsonSchema": { "type": "integer", "minimum": 0 }, "nullable": false, "handle": "count" } ], "name": "Build JSON snapshot", "moduleId": "n_7e339df7807ae34f", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_8ee956360dbca61f": { "name": "JSON snapshot", "kind": "outputs", "outputDefs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "response" }, { "jsonSchema": { "type": "integer", "minimum": 0 }, "nullable": false, "handle": "count" } ], "outputMappings": { "response": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_27895fb05fec3105", "output": "response" } ] }, "count": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_27895fb05fec3105", "output": "count" } ] } } } }, "edges": [ { "source": "n_aef8eeb45f19a46c", "target": "n_c99ec8f01da71301" }, { "source": "n_c99ec8f01da71301", "target": "n_27895fb05fec3105" }, { "source": "n_27895fb05fec3105", "target": "n_8ee956360dbca61f" } ] } }, "modules": { "n_7e339df7807ae34f": { "name": "Build JSON snapshot", "imports": [], "source": "export default function hackerNewsSnapshot({ body, statusCode, bodyEncoding = null }) {\n if (statusCode !== 200) throw new Error('Hacker News search did not return HTTP 200.');\n if (bodyEncoding !== null) throw new Error('Expected a JSON search response.');\n if (!body || typeof body !== 'object' || Array.isArray(body) || !Array.isArray(body.hits)) throw new Error('The search response must contain a hits array.');\n if (body.hits.length > 50) throw new Error('The search returned more than the requested fifty items.');\n const text = (value, name) => {\n if (value === null || value === undefined) return null;\n if (typeof value !== 'string') throw new Error('Invalid ' + name + ' in search result.');\n return value;\n };\n const items = body.hits.map(hit => {\n if (!hit || typeof hit !== 'object' || Array.isArray(hit)) throw new Error('Invalid search item.');\n if (hit.points !== null && hit.points !== undefined && (typeof hit.points !== 'number' || !Number.isFinite(hit.points))) throw new Error('Invalid points in search result.');\n return { title: text(hit.title, 'title'), points: hit.points ?? null, url: text(hit.url, 'url'), created_at: text(hit.created_at, 'created_at'), author: text(hit.author, 'author') };\n });\n return { response: JSON.stringify(items), count: items.length };\n}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }