JavaScript
The JavaScript function type allows you to run arbitrary JavaScript or TypeScript code.
It is defined like this:
type: javascript
code: |
module.exports = async function({ input, externalApiClient }) {
const response = await externalApiClient.post('/tasks', input)
return response.id
}The code should always export a single function as the default export.
Arguments
Arguments are all passed as a single object to the function exported from the code.
Additionally to function-specific arguments, the following arguments are added to all functions:
externalApiClient– API client configured with authentication that can be used to make requests to the external API. This parameter is available when code is executed in a context of a specific Connection.credentials– authentication credentials for the current connection (only available when externalApiClient is available)internalApiClient- API client configured to make requests to your product's API (also called Internal API). This client is only available in the context of App Data Schemas at the moment.engineApiClient– API client (MembraneClient instance) for interacting with the Membrane Engine API.
Logging
You can log messages to the console using the console.log function:
console.log("Fetching items...")To log a JSON object, you need to stringify it:
console.log(JSON.stringify(data))API Clients
JavaScript method implementations receive API client(s) named externalApiClient, internalApiClient, and engineApiClient as arguments. They can be used to make API requests to an external API (based on the current integration or connection), internal API (API of your product), and the Membrane Engine API respectively. The API clients are automatically configured with authentication and base URL settings - you don't need to provide authentication parameters into each request.
Making Requests
The API client provides methods for making HTTP requests:
interface ApiClient {
// GET request with optional query parameters
get(
path: string,
query?: Record<string, any>,
options?: RestApiClientOptions
): Promise<any>
// POST request with data
post(path: string, data?: any, options?: RestApiClientOptions): Promise<any>
// PUT request with data
put(path: string, data?: any, options?: RestApiClientOptions): Promise<any>
// PATCH request with data
patch(path: string, data?: any, options?: RestApiClientOptions): Promise<any>
// DELETE request with optional data
delete(path: string, data?: any, options?: RestApiClientOptions): Promise<any>
}Examples
// GET request with query parameters
const response = await apiClient.get("/items", {
page: 1,
limit: 10,
})
// POST request with data
const newItem = await apiClient.post("/items", {
name: "New Item",
description: "Description",
})
// PUT request to update
await apiClient.put("/items/123", {
name: "Updated Item",
})
// DELETE request
await apiClient.delete("/items/123")Request Options
Each request method accepts an optional options parameter that can override the default client configuration:
interface RestApiClientOptions {
// Base URI for relative paths
baseUri?: string
// Headers to add to the request
headers?: Record<string, string>
// Query parameters to add to all requests
query?: Record<string, string>
// Basic auth credentials
auth?: {
username: string
password: string
}
// Return full response instead of just data
returnFullResponse?: boolean
// Response type - how to parse the response
responseType?: "json" | "arraybuffer" | "stream"
}Example with Options
// Get JSON response (default)
const jsonResponse = await apiClient.get(
"/items",
{},
{
headers: {
Accept: "application/json",
},
}
)
// Download file as stream
const fileResponse = await apiClient.get(
"/files/123",
{},
{
responseType: "stream",
returnFullResponse: true,
}
)Response
By default, the API client:
- Returns the response body for successful requests (status 200–299)
- Throws an error for failed requests
- Handles authentication and rate limiting errors automatically
You can get the full response including status and headers by setting returnFullResponse: true in the options.
Using in Actions and Flow Nodes
You can use this function in actions or flow nodes with run-javascript type.
It is structured a bit differently than the standard definition. Here is an example:
name: Create Task
key: create-task
type: run-javascript
config:
code: |
module.exports = async function({ input, externalApiClient }) {
const response = await externalApiClient.post('/tasks', input)
return response.id
}Error Handling
The API client automatically handles common error cases:
- 401 responses trigger an ACCESS_TOKEN_EXPIRED error that will attempt to refresh credentials
- 429 responses trigger a RATE_LIMIT_EXCEEDED error that will retry the request with exponential backoff (only in asynchronous mode, e.g., within a flow run)
- Other error responses (status >= 300) throw a ConnectionError
Using in Connector Files
When used in connector functionality that is stored in connector files (i.e. everthing except functions in the connector definition itself), the code is written in a separate file named <function-name>.js.
For example:
// "Create" function of the "Contacts" data collection inside a connector.
// File location: data/contacts/create.js
module.exports = async function ({ parameters, externalApiClient, input }) {
const response = await externalApiClient.post("/contacts", input)
return {
id: response.id,
}
}Updated 29 days ago
