---
schema_version: "1"
id: 59c87567085130cf968a3c6595d2d55069891610e0b89ced7c1c4de112e16282
title: JavaScript Scripting Policy
collection: mulesoft
version: current
locale: en-us
portal_url: https://docs.salesforce.com/mulesoft/current/en-us/gateway/latest/policies-included-javascript-scripting.md
canonical_url: https://docs.mulesoft.com/gateway/latest/policies-included-javascript-scripting
source_site: docs.mulesoft.com
content_type: documentation
content_hash: b123d277ed556fd664266e7e267ca26a1fcea8ddc79e13fa66f1e8b0a19a98e5
description: MuleSoft Documentation Site
release: "1.14"
latest: true
---
---
product: Omni Gateway
version: 1.14
is-latest-version: true
keywords: javascript, scripting, transformation, request filter, response filter, api gateway, flex gateway, gateway, policy
---

# JavaScript Scripting Policy

> For the full documentation index, see: https://docs.mulesoft.com/llms.txt

<table><colgroup><col> <col></colgroup><tbody><tr><td><p><strong>Policy name</strong></p></td><td><p>JavaScript Scripting</p></td></tr><tr><td><p><strong>Summary</strong></p></td><td><p>Runs a user-supplied JavaScript module to inspect and modify requests and responses</p></td></tr><tr><td><p><strong>Category</strong></p></td><td><p>Transformation</p></td></tr><tr><td><p><strong>First Omni Gateway version available</strong></p></td><td><p>1.14.0</p></td></tr><tr><td><p><strong>Release Notes</strong></p></td><td><p><a href="https://docs.mulesoft.com/release-notes/gateway/policies/javascript-scripting-release-notes">JavaScript Scripting Policy</a></p></td></tr><tr><td><p><strong>Returned Status Codes</strong></p></td><td><p><code>500</code> - The script threw an error while processing the request or response</p></td></tr></tbody></table>

## Summary

The JavaScript Scripting policy runs a JavaScript module that you supply to inspect and modify HTTP
traffic as it passes through the gateway. Use the policy to add or change headers, transform request
or response bodies, and block a request with an early response.

The module runs as a standard JavaScript ES module and can export either or both of these functions:

- `requestFilter(request)` runs for every incoming request. It can read and modify the request,
  allow the request to continue to the upstream service, or terminate the request with an immediate
  response.

- `responseFilter(response, requestData)` runs for every upstream response. It can read and modify
  the response before the gateway returns it to the client.

The module must export at least one of these functions to properly load.

Module-level variables persist across invocations to share state between requests (for example, to
maintain a counter). The runtime provides the standard `console`, `TextEncoder`, and `TextDecoder`
globals. The script runs synchronously; `async` functions and promises returned from a filter aren’t
awaited.

## Configure Policy Parameters

### Omni Gateway Local Mode

\- policyRef: name: javascript-scripting-flex config: script: <string> // REQUIRED - JavaScript ES
module source

<table><colgroup><col> <col> <col> <col></colgroup><thead><tr><th>Parameter</th><th>Required</th><th>Default Value</th><th>Description</th></tr></thead><tbody><tr><td><div><div><p><code>script</code></p></div></div></td><td><div><div><p>Required</p></div></div></td><td><div><div><p>—</p></div></div></td><td><div><div><p>The full source text of a JavaScript ES module. The module must export at least one of <code>requestFilter</code> or <code>responseFilter</code>.</p></div></div></td></tr></tbody></table>

### Managed Omni Gateway and Omni Gateway Connected Mode

When you apply the policy from the UI, the following parameters are displayed:

<table><colgroup><col> <col></colgroup><thead><tr><th>Parameter</th><th>Description</th></tr></thead><tbody><tr><td><div><div><p>Policy type</p></div></div></td><td><div><div><p>JavaScript Scripting</p></div></div></td></tr><tr><td><div><div><p>Script</p></div></div></td><td><div><div><p>The JavaScript ES module that exports <code>requestFilter</code> and/or <code>responseFilter</code></p></div></div></td></tr></tbody></table>

## Script API

The gateway calls the exported functions and passes objects that represent the request or response.
These objects can’t be constructed from JavaScript.

### Filter Functions

<table><colgroup><col> <col></colgroup><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody><tr><td><div><div><p><code>requestFilter(request)</code></p></div></div></td><td><div><div><p>Called for each incoming request. Receives a <code>request</code> object. Returns a flow result that controls whether the request continues to the upstream service or is stopped with an early response. Returning <code>undefined</code> continues the request.</p></div></div></td></tr><tr><td><div><div><p><code>responseFilter(response, requestData)</code></p></div></div></td><td><div><div><p>Called for each upstream response. Receives a <code>response</code> object and the <code>requestData</code> value carried from <code>requestFilter</code>. The return value is ignored.</p></div></div></td></tr></tbody></table>

### Request and Response Objects

Both the `request` and `response` objects expose the same methods to read and modify headers and the
body:

<table><colgroup><col> <col></colgroup><thead><tr><th>Method</th><th>Description</th></tr></thead><tbody><tr><td><div><div><p><code>getHeaders()</code></p></div></div></td><td><div><div><p>Returns all headers as an array of <code>[name, value]</code> pairs.</p></div></div></td></tr><tr><td><div><div><p><code>setHeaders(headers)</code></p></div></div></td><td><div><div><p>Replaces all headers with the provided array of <code>[name, value]</code> pairs.</p></div></div></td></tr><tr><td><div><div><p><code>getHeader(name)</code></p></div></div></td><td><div><div><p>Returns the value of the first header matching <code>name</code> (case-insensitive), or <code>undefined</code> if absent.</p></div></div></td></tr><tr><td><div><div><p><code>setHeader(name, value)</code></p></div></div></td><td><div><div><p>Sets a header, replacing any existing values for that name.</p></div></div></td></tr><tr><td><div><div><p><code>addHeader(name, value)</code></p></div></div></td><td><div><div><p>Appends a header, preserving any existing values for that name.</p></div></div></td></tr><tr><td><div><div><p><code>removeHeader(name)</code></p></div></div></td><td><div><div><p>Removes all headers matching <code>name</code>.</p></div></div></td></tr><tr><td><div><div><p><code>getBody()</code></p></div></div></td><td><div><div><p>Returns the body as a <code>Uint8Array</code>.</p></div></div></td></tr><tr><td><div><div><p><code>setBody(body)</code></p></div></div></td><td><div><div><p>Replaces the body with the provided <code>Uint8Array</code>. Throws an error if the entity has no body or if the body exceeds the 1 MiB maximum.</p></div></div></td></tr><tr><td><div><div><p><code>getBodyString()</code></p></div></div></td><td><div><div><p>Returns the body decoded as a UTF-8 string. Invalid byte sequences are replaced with the Unicode replacement character (<code>U+FFFD</code>).</p></div></div></td></tr><tr><td><div><div><p><code>setBodyString(body)</code></p></div></div></td><td><div><div><p>Replaces the body with the UTF-8 encoding of the provided string. Throws an error if the entity has no body or if the encoded body exceeds the 1 MiB maximum.</p></div></div></td></tr><tr><td><div><div><p><code>containsBody()</code></p></div></div></td><td><div><div><p>Returns <code>true</code> if the entity has a body, or <code>false</code> otherwise. Use this to check whether body operations are safe before you call them.</p></div></div></td></tr></tbody></table>

### Controlling Request Flow

The value that `requestFilter` returns controls whether the request continues:

- Return `undefined` or `{ flow: "continue" }` to allow the request to continue to the upstream
  service.

- Return `{ flow: "continue", data: <value> }` to continue and pass `data` to `responseFilter`. The
  `requestData` argument of `responseFilter` receives `{ flow: "continue", data: <value> }`.

- Return `{ flow: "break", response: { statusCode, headers, body } }` to stop the request and send
  an immediate response to the client. The upstream service is not called. `headers` is an array of
  `[name, value]` pairs, and `body` is optional and can be a `Uint8Array` or a string.

If `requestFilter` returns an unexpected value, the gateway logs a warning and treats it as
continue.

### Error Handling

If a filter function throws an error, the gateway stops processing and returns a `500` response with
the JSON body `{"error":"Internal error"}` to the client. The error is written to the gateway logs.

## Logging

Calls to the `console` methods are written to the gateway logs at the corresponding level:

<table><colgroup><col> <col></colgroup><thead><tr><th>Console method</th><th>Gateway log level</th></tr></thead><tbody><tr><td><div><div><p><code>console.debug()</code></p></div></div></td><td><div><div><p>debug</p></div></div></td></tr><tr><td><div><div><p><code>console.log()</code>, <code>console.info()</code></p></div></div></td><td><div><div><p>info</p></div></div></td></tr><tr><td><div><div><p><code>console.warn()</code></p></div></div></td><td><div><div><p>warn</p></div></div></td></tr><tr><td><div><div><p><code>console.error()</code></p></div></div></td><td><div><div><p>error</p></div></div></td></tr></tbody></table>

## Examples

### Add and Remove Headers

This example adds a header to the request and the response, and removes a header from each:

\- policyRef: name: javascript-scripting-flex config: script: | export function
requestFilter(request) { request.setHeader("x-processed-by", "javascript-policy");
request.removeHeader("x-internal"); }

      export function responseFilter(response) {
        response.setHeader("x-served-by", "omni-gateway");
        response.removeHeader("server");
      }

### Block a Request with an Early Response

This example rejects a request that is missing an API key and returns a `401` response without
calling the upstream service:

\- policyRef: name: javascript-scripting-flex config: script: | export function
requestFilter(request) { if (!request.getHeader("x-api-key")) { return { flow: "break", response: {
statusCode: 401, headers: \[\["content-type", "text/plain"\]\], body: "Missing API key", }, }; } }

### Pass Data from the Request to the Response

This example reads a value during the request phase and uses it during the response phase:

\- policyRef: name: javascript-scripting-flex config: script: | export function
requestFilter(request) { const id = request.getHeader("x-request-id") || "unknown"; return { flow:
"continue", data: { id } }; }

      export function responseFilter(response, requestData) {
        if (requestData.flow === "continue" && requestData.data) {
          response.setHeader("x-request-id", requestData.data.id);
        }
      }

### Transform the Response Body

This example replaces the response body with a new string:

\- policyRef: name: javascript-scripting-flex config: script: | export function
responseFilter(response) { if (response.containsBody()) {
response.setBodyString('{"message":"transformed by gateway"}'); response.setHeader("content-type",
"application/json"); } }
