JavaScript where connectors fall short
Drop a JS Code node on the canvas and write JavaScript where connectors fall short — map messy payloads, normalize dates and enums, strip PII, then hand a clean object to the next app step. No sidecar service. No leaving WEXTL.
- GDPR
- Data Encryption
- 2FA
- Local Data Region
Typeform into a JS Code node that maps fields, then Pipedrive and Slack
What Custom Functions (JS) helps you do
JavaScript between the apps you already use
The JS Code node is a first-class step — same ports, same run history as every other node.
- 1
Drop JS Code after the mismatch
Insert the node right after the step whose output doesn't match the next app's fields — a Typeform webhook, an HTTP response, a database action, or another app's payload.
- 2
Reference input, return the shape
Read the upstream node's output via input.nodes["<nodeId>"], reshape it with plain JavaScript — or a curated import like date-fns or zod — and return the exact object the next node expects, no wrapper key required.
- 3
Run, inspect, or branch on failure
Open run history to see the return value and any console.log output from that pass; an uncaught error marks the node failed instead of quietly passing bad data downstream.
Map vendor JSON before CRM create
A form or webhook sends {"cell_phone":"+1 415…", "co":"Acme"} and Pipedrive wants {phone, company}. A JS Code step reads that object off input.nodes, renames the fields, coalesces empty strings to null, and returns the exact literal Pipedrive's create-person action expects — no wrapper key, no separate mapping UI to learn.
It runs as a step on the same canvas as Typeform, CRM, and Slack, not a separate microservice you deploy and monitor elsewhere.
Reviewers see the blue JS Code node between Typeform and Pipedrive — not a mystery Lambda in another AWS account.
Typeform into JS Code map step, then Pipedrive and Slack
Normalize HTTP responses before a branch
Internal APIs return nested arrays, stringly-typed numbers ("42" instead of 42), and inconsistent nulls. JS Code flattens data.items[0].attributes.status_code down to a top-level status field so a Filter step can branch on it directly.
Wrap the JSON.parse in try/catch and return {ok:false, reason: e.message} on a bad payload — the Filter branches on ok instead of the whole run crashing on one malformed response.
Failed parses show up on that JS Code step in run history, with the stack trace attached — you fix the transform, not grep CloudWatch in another account.
The isolate ships with a curated module set baked in — lodash, dayjs, date-fns, zod, uuid, nanoid, papaparse, fast-xml-parser, jsonpath-plus, and slugify — so import { z } from 'zod' or import { JSONPath } from 'jsonpath-plus' resolves with no package.json, lockfile, or build step to keep patched.
HTTP into JS Code normalize, then Filter to Sheets or Slack
Score and strip PII before send
Before Gmail or an agent step auto-sends, a regex-based redaction pass in JS Code masks emails and phone numbers, then computes a confidence score your policy Filter reads.
Safe path sends; anything under your threshold routes to Slack for human review — the redaction and scoring logic stays JavaScript on the canvas, not a compliance rule buried in a vendor's black box.
The score and the redacted fields are both visible on that run — reviewers can see exactly what the guardrail decided and why.
console.log, warn, and error calls inside that step stream to the node's panel in the run viewer as the isolate executes, and each pass is metered by isolate time and capped at 300 seconds by default (your plan may set a different limit) — a runaway loop fails that node instead of silently hanging the workflow.
Outlook into JS Code PII/score step, then policy branch to Gmail or Slack







