Add a CSV node to parse and build CSV data #423
Replies: 1 comment 1 reply
|
Hi @asimodabas , First of all, thank you for the thoughtful proposal and for offering to contribute 🤗 We agree that, even with our native AI workflow builder and expression generator, a dedicated converter would be a meaningful UX improvement. It would make common data transformations simpler and more accessible in visual workflows. Please follow the repository’s AGENTS.md and contribution guidelines when preparing the PR, including the required tests, UI coverage where practical, and documentation updates. |
Uh oh!
There was an error while loading. Please reload this page.
[Feature]: Add a CSV node to parse and build CSV data
Problem
Heym has data nodes for Google Sheets, Grist, DataTable, and BigQuery, but there is no simple, dependency-free way to work with raw CSV text inside a workflow. A very common need in data / AI pipelines is to:
Today this requires the Code node or manual expression logic, which is more effort than a dedicated node would be.
Proposal
Add a first-class CSV node (category: Data) with two operations:
parse— CSV text → array of row objects (keyed by header) or array of arrays.build— array of row objects/arrays → CSV text.The node needs no credentials — it is a pure in-memory transform, so it slots cleanly next to
set,merge, andjsonOutputMapper.Not already covered
CSV currently only exists as a file conversion / export format — e.g. the Google Drive node can convert a stored file to CSV (
driveConvertTargetFormat: "csv"), and CSV is a recognized file/attachment type. There is no standalone, credential-free node that parses raw CSV text into rows or builds CSV text from rows inline in a workflow. This proposal is that missing transform node, not a change to the existing Drive conversion.Proposed fields
parse:csvText(string, expression-capable) — the input CSVdelimiter(string, default,)hasHeader(boolean, defaulttrue) — first row is the headertrimValues(boolean, defaulttrue)build:rows(expression-capable) — array of objects or arraysdelimiter(string, default,)includeHeader(boolean, defaulttrue)columns(optional string list) — explicit column orderExample I/O
parse:build:Affected areas
Backend:
backend/app/services/node_execution/nodes/csv_node.py— new handlerbackend/app/services/node_execution/registry.py— register the handlerbackend/app/models/schemas.py— node/operation schema metadatabackend/app/services/workflow_dsl_prompt.py— DSL fields, defaults, expression/autofill hintsFrontend:
frontend/src/types/node.ts— node type registrationfrontend/src/components/Panels/propertiesPanel/nodes/CsvNodeProperties.vue— config UIfrontend/src/lib/nodeIcons.ts— iconDocs (per the node-integration policy):
frontend/src/docs/content/nodes/csv-node.mdfrontend/src/docs/manifest.tsfrontend/src/docs/content/reference/features.mdandnode-types.mdHow to test
The feature can be verified at three levels so we can prove both correctness and no regression to existing flows.
1. Correctness — new node unit tests
Add
backend/tests/test_csv_node.py(pure, deterministic — no external services), following the existing node-handler test style (unittest+ aSimpleNamespaceexecutor stub). Cases:parsewith header → list of dicts keyed by headerparsewithhasHeader: false→ list of lists"Smith, Jr.";), andtrimValueson/off{ "rows": [] }buildfrom dicts with/without header, customcolumnsorderbuildescaping: values containing the delimiter, quotes, or newlines are quoted correctlybuild(parse(x)) == xfor a representative sample2. No regression — full backend suite + guard tests
Because the node is purely additive, every existing test must still pass unchanged. The repo already ships guard-style tests that catch cross-cutting breakage, e.g.
backend/tests/test_workflow_json_compatibility.py(workflow JSON backward compatibility) and the DSL-prompt tests. Running the full backend suite should stay green.3. UI — Playwright E2E
A spec mirroring the existing node-property specs (
jira-node-properties.spec.ts,playwright-node-properties.spec.ts) can confirm the node is addable to the canvas, both operations render their fields, and expression-capable fields open the expression dialog.The usual
./check.sh(lint + typecheck + backend tests) and the E2E PR job gate all of the above.Alternatives considered
The Code node can parse/build CSV, but that requires writing Python per workflow and loses the visual, typed, expression-friendly experience. A dedicated node matches how Heym treats other data formats.
I'm happy to open a PR for this if it's welcome.
All reactions