Skip to content

Where Your Code Runs ​

You can write JavaScript in several places. They share one core set of names, and a few places add their own. Use this page to see what you can use where.

The basics (every place) ​

  • Your code always runs as an async function. Use await anywhere, with no setup. await httpClient.get(...) just works.
  • return sends a value on. Without it the result is empty.
  • input is the previous block's output. It is local to the code, so it never leaks into variables.
  • A name you assign without const, let or var becomes a request variable that later blocks can read. See Scripting Context.
  • Libraries are not built in. Only jwt is. Install anything else (Day.js, Zod, Lodash...) in Project Settings > npm Packages and import it. See Imports & Libraries.

All the places ​

WhereYou write code inAdds
Route (HTTP request)JS Runner, Transformer, js: fields and conditions on any blockThe core names
Workflow (started by a trigger, a schedule, Trigger Workflow or the Run button)The same blocks and fieldsThe core names, with different values
Custom blockThe same blocks, inside the block's own canvasparams, the settings filled in where the block is used. See Custom Blocks
Middleware custom blockThe same blocks, inside the block's own canvasThe core names, but no params: a middleware block takes no settings. After the route, input starts as { httpCode, body }, and getResponseBody() / getResponseStatus() return the reply. See Middlewares
DB Native blockIts JS fielddbQuery(query, params?) on PostgreSQL and MySQL, db and ObjectId on MongoDB. See DB Native
KV Raw Connection blockIts JS fieldkv, the raw client. See KV Raw Connection
Test-only custom block (setup and teardown)The block's canvastestsuite. See Setup and Teardown
Request validation ("Use JavaScript" on a field)The field's code boxinput is the field's value. Return a truthy value to pass, or throw new ValidationError(...). See Routing. No import here.
Test hooks and checksThe Hooks and Checks tabs of a suitet and fluxify, not the names on this page. See Hooks and Checks
Workflow test input scriptThe suite's input tabWorks like a JS block. See Testing Workflows

Core names ​

Available in every block and js: field of a route, workflow and custom block. The full list with types is the JavaScript API Reference.

NameWhat it is
inputThe previous block's output
outputsOutputs saved with Save output to variable, by name. It does not exist until a block has saved one, so use outputs?.name if unsure
triggerWhat started this run
getRequestBody(), getQueryParam(k), getRouteParam(k), getHeader(k), getCookie(k)Read the request
httpRequestMethod, httpRequestRouteThe method and path of the request
setHeader(k, v), setCookie(name, options)Add to the response
getResponseBody(), getResponseStatus()The reply, in an after middleware. null anywhere else
getConfig(key)A value from App Config
httpClientCall other services
loggerlogInfo, logWarn, logError
jwtsign, verify, decode
ValidationErrorAn error class for request validators

Routes and workflows ​

A workflow has no HTTP request, so the request names exist but are empty:

NameIn a routeIn a workflow
getRequestBody()The request bodyThe payload the run was given (the same value as input at the start)
getQueryParam, getRouteParam, getHeader, getCookieThe request values, "" when missing (undefined for getQueryParam)Always "" (undefined for getQueryParam)
httpRequestMethod"GET", "POST"...""
httpRequestRouteThe request pathAn internal id, not a URL
setHeader, setCookieAdd to the responseDo nothing, there is no response
triggerkind: "route", source: "http", no datakind: "trigger", with the events in trigger.data

A route called with the header x-fluxify-reply: async runs in the background and answers 202 straight away. setHeader and setCookie do nothing there either.

trigger ​

typescript
trigger: {
  kind: "route" | "job" | "workflow" | "cron" | "trigger";
  source: string;   // "http", "internal", "schedule", "kafka", "nats"...
  reply: "sync" | "async";
  id?: string;
  data: { data: any; meta: { id?: string; receivedAt?: string; source?: string } }[];
  meta: { batchId: string; size: number; attempt?: number; /* ... */ };
  connection?: { raw; commit(); moveToDLQ(error?); lag() };   // queue triggers only
}
  • Use trigger.source to tell runs apart. A schedule is kind: "trigger" with source: "schedule". The Trigger Workflow block and the Run button are source: "internal".
  • trigger.data is always a list, even for one event. input is the bare payload when there is exactly one event, and a list of payloads when there are more.
  • kind: "job" is a custom block that was queued to run later. The values "workflow" and "cron" are reserved and not used yet.
  • Full details, batching and the queue controls are in Triggers.

Time limits ​

Your code has no separate time limit. The whole run has one:

  • Routes: the route's timeout setting (30 seconds by default). It is enforced by the experimental worker watchdog, which you turn on with experimental.workerTimeouts.enabled.
  • Workflows: the workflow's own timeout setting (300 seconds by default).

Keep waits short and give outgoing calls their own timeout. See Execution Limits & Safety.

Released under the Apache License 2.0. Enterprise features are under the Fluxify Enterprise Edition License.