---
updatedAt: 2026-09-29T09:01:43.000Z
agentTools:
  siteIndex: https://docs.jfrog.com/llms.txt
  projectIndex: https://docs.jfrog.com/administration/llms.txt
---

# TypeScript Code for Workers

The minimal expected code is a function exported as default that should return the result of the worker’s script execution.

<Callout icon="📘" theme="info">
  **Note**

  The supported TypeScript version in the JFrog Platform is ES2022, with the default configuration.
</Callout>

For example:

```
export default async function MyFunction() {

   // Do what you want

   return {
       status: 'DOWNLOAD_PROCEED',
       message: 'proceed',
   }
}
```

To enhance the developer experience we have chosen to use TypeScript. The worker function takes two inputs, which are injected.

```
export default async function (context: PlatformContext, data: T) Promise<U> {

   // Do what you want

   return {
       status: 'DOWNLOAD_PROCEED',
       message: 'proceed',
   }
}
```

Where T and U types stand for the data type (for example, BeforeDownloadRequest) and the expected returned response (like BeforeDownloadResponse for BeforeDownloadRequest).

Event payloads include a `userContext` object for the user or token that triggered the event. The object contains `id` (user ID or token ID), `isToken`, and `realm`. For more information, see [Configure Workers for Custom Flows](/docs/configure-workers-for-custom-flows).

You can give a name to your function for convenience. You can also use anonymous functions instead.

The code editor also supports arrow functions. The samples provided in the documentation use arrow functions.

## TypeScript APIs

You can use the following common interface types in your Worker code.

* [PlatformContext](#platformcontext)
* [PlatformCrypto](#platformcrypto)
* [PlatformClients](#platformclients)
* [PlatformHttpClient](#platformhttpclient)
* [IPlatformHttpResponse](#iplatformhttpresponse)
* [PlatformHttpClientError](#platformhttpclienterror)
* [StateManager](#statemanager)

<Callout icon="❗️" theme="error">
  **Important**

  Import statements are not allowed in the code, but you can use JavaScript natives.

  Timing functions such as `setTimeout`, `setInterval`, or `setImmediate` are part of the Node.js API, which is disabled in the Worker sandbox.
</Callout>

## PlatformContext

```
interface PlatformContext {
   baseUrl: string; // platform base URL
   clients: PlatformClients; // clients to communicate with the platform or external resources
   platformToken: string; // platform access token
   wait: (delayMs: number) => Promise<void> // creates a promise that resolves after "duration" expressed in millisecondes
   state: StateManager; // State manager to store and retrieve state for this Worker between executions
   getRemainingExecutionTime: () => number // remaining milliseconds before the Worker execution times out
   crypto: PlatformCrypto; // hash, HMAC, and cryptographically secure random bytes
}
```

## PlatformCrypto

Use `context.crypto` to hash data, compute HMAC values, and generate cryptographically secure random bytes in a Worker script. The Node.js `crypto` module is not available in the Worker sandbox. These methods are available from Workers 1.306.0.

Supported hash and HMAC algorithms are `sha256` and `sha512`. The `encoding` argument is optional and defaults to `hex`. You can also set it to `base64`. `randomBytes` generates at most 4096 bytes.

For example:

```
export default async (context: PlatformContext): Promise<any> => {
  const digest = context.crypto.hash('sha256', 'hello');
  const hmac = context.crypto.hmac('sha256', 'secret', 'hello');
  const nonce = context.crypto.randomBytes(32);
  const digestBase64 = context.crypto.hash('sha512', 'hello', 'base64');

  return { digest, hmac, nonce, digestBase64 };
};
```

<Callout icon="📘" theme="info">
  **PlatformCrypto Errors**

  * An unsupported hash algorithm raises `Unsupported hash algorithm '<algorithm>'. Supported: sha256, sha512`.
  * An unsupported HMAC algorithm raises `Unsupported hmac algorithm '<algorithm>'. Supported: sha256, sha512`.
  * An unsupported encoding raises `Unsupported encoding '<encoding>'. Supported: hex, base64`.
  * A `randomBytes` size that is not a positive integer raises `crypto.randomBytes size must be a positive integer`.
  * A `randomBytes` size greater than 4096 raises `crypto.randomBytes size cannot exceed 4096 bytes`.
</Callout>

```
interface PlatformCrypto {
  /**
   * Computes a cryptographic hash of the given data
   * @param {string} algorithm - The hash algorithm to use. Supported: 'sha256', 'sha512'
   * @param {string} data - The data to hash
   * @param {string} encoding - The output encoding. Defaults to 'hex'
   */
  hash(algorithm: 'sha256' | 'sha512', data: string, encoding?: 'hex' | 'base64'): string;

  /**
   * Computes an HMAC of the given data using the given key
   * @param {string} algorithm - The hash algorithm to use. Supported: 'sha256', 'sha512'
   * @param {string} key - The HMAC key
   * @param {string} data - The data to authenticate
   * @param {string} encoding - The output encoding. Defaults to 'hex'
   */
  hmac(algorithm: 'sha256' | 'sha512', key: string, data: string, encoding?: 'hex' | 'base64'): string;

  /**
   * Generates cryptographically secure random bytes
   * @param {number} size - The number of random bytes to generate
   * @param {string} encoding - The output encoding. Defaults to 'hex'
   */
  randomBytes(size: number, encoding?: 'hex' | 'base64'): string;
}
```

## PlatformClients

**Axios**

The object `axios` is available inside the script. You can use this object to perform external calls. For more information, refer to the <Anchor label="Axios Documentation" target="_blank" href="https://github.com/axios/axios#readme">Axios Documentation</Anchor>.

```
interface PlatformClients {
   platformHttp: PlatformHttpClient // generic HTTP client to communicate with the platform. Hostname and token are set automatically.
   axios: AxiosInstance // generic HTTP client to communicate with external web resources.
}
```

### Fire-and-Forget Methods

Fire-and-forget HTTP calls let Workers trigger notifications or downstream jobs without waiting for a response. The JFrog Platform schedules the request and moves on, so a long external call does not hold the Worker open or cause an execution timeout. Use a standard awaited HTTP call when the Worker needs the response to determine what happens next.

These methods are on `context.clients.axios`. They schedule the HTTP request and return immediately. For examples, see [fire-and-forget HTTP calls](/docs/optimize-workers-within-platform-limits#use-fire-and-forget-http-calls-for-long-running-external-requests).

<Callout icon="📘" theme="info">
  **Note**

  A successful Worker run means only that the request was scheduled. It doesn't mean the other system received the request, returned a 200 status, or finished the work.
</Callout>

```
export interface ExtendedAxios {
    /**
     * Triggers an HTTP GET request and does not wait for the response (fire-and-forget).
     * Note: completion is not guaranteed. If the target server ties request processing to the client connection, it may abort the work when the client disconnects.
     */
    getAndForget: <D = any, P = any>(
        url: string,
        config?: AxiosRequestConfig<D, P>
    ) => void;

    /**
     * Triggers an HTTP PUT request and does not wait for the response (fire-and-forget).
     * Note: completion is not guaranteed. If the target server ties request processing to the client connection, it may abort the work when the client disconnects.
     */
    putAndForget: <D = any, P = any>(
        url: string,
        data?: D,
        config?: AxiosRequestConfig<D, P>
    ) => void;

    /**
     * Triggers an HTTP POST request and does not wait for the response (fire-and-forget).
     * Note: completion is not guaranteed. If the target server ties request processing to the client connection, it may abort the work when the client disconnects.
     */
    postAndForget: <D = any, P = any>(
        url: string,
        data?: D,
        config?: AxiosRequestConfig<D, P>
    ) => void;

    /**
     * Triggers an HTTP DELETE request and does not wait for the response (fire-and-forget).
     * Note: completion is not guaranteed. If the target server ties request processing to the client connection, it may abort the work when the client disconnects.
     */
    deleteAndForget: <D = any, P = any>(
        url: string,
        config?: AxiosRequestConfig<D, P>
    ) => void;

    /**
     * Triggers an HTTP HEAD request and does not wait for the response (fire-and-forget).
     * Note: completion is not guaranteed. If the target server ties request processing to the client connection, it may abort the work when the client disconnects.
     */
    headAndForget: <D = any, P = any>(
        url: string,
        config?: AxiosRequestConfig<D, P>
    ) => void;

    /**
     * Triggers an HTTP PATCH request and does not wait for the response (fire-and-forget).
     * Note: completion is not guaranteed. If the target server ties request processing to the client connection, it may abort the work when the client disconnects.
     */
    patchAndForget: <D = any, P = any>(
        url: string,
        data?: D,
        config?: AxiosRequestConfig<D, P>
    ) => void;

    /**
     * Triggers an HTTP REQUEST and does not wait for the response (fire-and-forget).
     * Note: completion is not guaranteed. If the target server ties request processing to the client connection, it may abort the work when the client disconnects.
     */
    requestAndForget: <D = any, P = any>(
        config: AxiosRequestConfig<D, P>
    ) => void;
}
```

## PlatformHttpClient

PlatformHttpClient relies on Axios to perform HTTP requests. It is a ready to use client to call any JFrog Platform REST API. The `endpoint` input must be a relative URL with the pattern `<serviceName>/api/<endpoint>`. For example, the methods of the PlatformHttpClient, `/artifactory/api/system/ping`, return an object of type `IPlatformHttpResponse` or throw an object of type `PlatformHttpClientError` as error.

Use `request(method, body, headers)` when you need to send a request body with DELETE, or to specify a custom method, body, and headers. The `get`, `post`, `put`, `patch`, and `delete` methods are unchanged. The `delete` method does not accept a request body.

```
interface PlatformHttpClient {
   /**
    * Perform HTTP GET request to the JFrog Platform
    * @param {string} endpoint - API endpoint. For example, /artifactory/api/repositories
    * @param {Record<string, string>} headers - additional headers used in the request
    */
   get(endpoint: string, headers?: Record<string, string>): Promise<IPlatformHttpResponse>


   /**
    * Perform HTTP POST request to JFrog platform
    * @param {string} endpoint - API endpoint. For example, /artifactory/api/repositories
    * @param {any} requestData - data sent in request body
    * @param {Record<string, string>} headers - additional headers used in the request
    */
   post(endpoint: string, requestData?: any, headers?: Record<string, string>): Promise<IPlatformHttpResponse>


   /**
    * Perform HTTP PUT request to JFrog platform
    * @param {string} endpoint - API endpoint. For example, /artifactory/api/repositories
    * @param {any} requestData - data sent in request body
    * @param {Record<string, string>} headers - additional headers used in the request
    */
   put(endpoint: string, requestData?: any, headers?: Record<string, string>): Promise<IPlatformHttpResponse>


   /**
    * Perform HTTP PATCH request to JFrog platform
    * @param {string} endpoint - API endpoint. For example, /artifactory/api/repositories
    * @param {any} requestData - data sent in request body
    * @param {Record<string, string>} headers - additional headers used in the request
    */
   patch(endpoint: string, requestData?: any, headers?: Record<string, string>): Promise<IPlatformHttpResponse>


   /**
    * Perform HTTP DELETE request to JFrog platform
    * @param {string} endpoint - API endpoint. For example, /artifactory/api/repositories
    * @param {Record<string, string>} headers - additional headers used in the request
    */
   delete(endpoint: string, headers?: Record<string, string>): Promise<IPlatformHttpResponse>


   /**
    * Perform an HTTP request to the JFrog Platform. Use this method when you need to send a body with DELETE, or to specify the HTTP method, body, and headers without changing get, post, put, patch, or delete.
    * @param {string} method - HTTP method. For example, GET, POST, PUT, PATCH, or DELETE
    * @param {any} body - data sent in the request body, including for DELETE
    * @param {Record<string, string>} headers - additional headers used in the request
    */
   request(method: string, body?: any, headers?: Record<string, string>): Promise<IPlatformHttpResponse>
}
```

## IPlatformHttpResponse

```
interface IPlatformHttpResponse {
   /**
    * HTTP status
    */
   status: number;
   /**
    * Response headers
    */
   headers: Record<string, string>;
   /**
    * Parsed response body
    */
   data: any;
}
```

## PlatformHttpClientError

```
interface PlatformHttpClientError {
    /**
     * The reason of the error
     */
    message: string;

    /**
     * Http status
     */
    status: number;
}
```

## StateManager

This interface allows you to set or modify a Worker state at runtime, which persists between Worker runs. For example:

```
export default async (context: PlatformContext): Promise<any> => {
  context.state.has('foo'); // false
  context.state.set('foo', 'bar');
  context.state.has('foo'); // true

  return context.state.getAll(); // { "foo": "bar" }
};
```

The state is stored as a string: to safely retrieve a number, use the following syntax:

```
const numberStr = context.state.get('number');
const number = Number.parseInt(numberStr) || 0;
```

This code will try to get the property ‘number’ from the state and convert it to a number. If it doesn't exist or cannot be parsed, the code returns 0.

<Callout icon="📘" theme="info">
  **StateManager Limitations**

  * The state tool does not support concurrent executions of the same Worker.
  * In case of execution failure, the state will not be saved.
  * A Worker state can hold a maximum of 10 items by default: Self-Managed users can change this value in ​[Workers YAML Configuration](/installation/docs/worker-yaml-configuration)​​.
  * A state item key-value pair cannot exceed 40 characters for the key and 250 characters for the value.
</Callout>

```
interface StateManager {
    /**
     * Retrieves a value from the state by its key
     * @param {string} key - The key of the value to retrieve
     */
    get(key: string): string;
    /**
     * Sets a value in the state by its key
     * @param {string} key - The key of the value to set
     * @param {any} value - The value to set. If the value is not a string, it will be converted to a JSON string.
     */
    set(key: string, value: any): void;
    /**
     * Checks if a value exists in the state by its key
     * @param {string} key - The key of the value to check
     * @returns {boolean} - True if the value exists, false otherwise
     */
    has(key: string): boolean;
    /**
     * Deletes a value from the state by its key.
     * If it does not exist, it does nothing.
     * @param {string} key - The key of the value to delete
     */
    delete(key: string): void;
    /**
     * Clears the entire state
     */
    clear(): void;
    /**
     * Returns a copy of the entire state
     */
    getAll(): Record<string, string>;
}
```