npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@gravityforms/request

v6.1.0

Published

Utility to make WordPress REST API requests. It's a wrapper around window.fetch.

Readme

@gravityforms/request

HTTP request utilities for Gravity Forms products. Provides wrappers around window.fetch for common use cases including WordPress AJAX and the Hermes GraphQL-like API.

Installation

npm install @gravityforms/request

Exports

| Export | Description | |--------|-------------| | get | Simple GET request wrapper | | post | POST request with automatic form data encoding | | createHermesClient | Factory for Hermes API client with template literals | | serialize | Serialize JavaScript values for Hermes queries | | raw | Mark strings for raw insertion without serialization | | args | Helper for object argument serialization (combines raw + serialize) | | request (default) | Configuration-based request handler |


post

The most commonly used export. Makes POST requests to WordPress AJAX endpoints with automatic form data encoding.

Usage

import endpoint from 'ajaxUrl'; // Webpack alias for WordPress ajaxurl
import { post } from '@gravityforms/request';

const saveData = async ( data ) => {
    const response = await post( {
        endpoint,
        body: {
            action: 'my_ajax_action',
            security: window.myPlugin.nonce,
            ...data,
        },
    } );

    if ( response?.data?.success ) {
        console.log( 'Saved:', response.data );
    } else {
        console.error( 'Error:', response?.error || response?.data );
    }
};

Parameters

| Parameter | Type | Description | |-----------|------|-------------| | endpoint | string | The URL to POST to | | body | object | Request body (automatically converted to FormData) | | headers | object | Optional HTTP headers | | options | object | Optional fetch options |

Response

{
    data: { ... },    // Parsed JSON response
    status: 200,      // HTTP status code
}
// Or on error:
{
    error: Error      // Error object with .detail property
}

get

Simple GET request wrapper.

Usage

import { get } from '@gravityforms/request';

const fetchData = async () => {
    const response = await get( '/wp-json/my/v1/endpoint', {
        headers: { 'X-Custom-Header': 'value' },
    } );
    return response.json();
};

Parameters

| Parameter | Type | Description | |-----------|------|-------------| | endpoint | string | The URL to fetch | | params | object | Optional fetch options |


Hermes Client

For interacting with the Hermes GraphQL-like API. Uses template literals for intuitive query construction.

createHermesClient

Creates a configured client with query and mutation functions.

import { createHermesClient, serialize, raw, args } from '@gravityforms/request';

const client = createHermesClient( {
    endpoint: window.ajaxurl,
    queryAction: 'gcrm_hermes_query',
    mutationAction: 'gcrm_hermes_mutation',
    security: window.gcrm.nonce,
    onLoadingChange: ( isLoading ) => {
        // Optional: track loading state
    },
} );

Configuration Options

| Option | Type | Required | Description | |--------|------|----------|-------------| | endpoint | string | Yes | AJAX endpoint URL | | queryAction | string | Yes | WordPress action for queries | | mutationAction | string | Yes | WordPress action for mutations | | security | string | Yes | Security nonce | | queryKey | string | No | Body key for queries (default: 'query') | | mutationKey | string | No | Body key for mutations (default: 'mutation') | | headers | object | No | Custom headers for all requests | | options | object | No | Custom fetch options | | onLoadingChange | function | No | Callback when loading state changes |

Query Examples

const { query, mutation } = client;

// Simple query
const contacts = await query`{
    contact(limit: 10) {
        id,
        firstName,
        lastName
    }
}`;

// Query with interpolated values
const limit = 20;
const searchTerm = 'John';
const results = await query`{
    contact(limit: ${ limit }, search: ${ searchTerm }) {
        id,
        firstName,
        lastName,
        email { address, isPrimary }
    }
}`;

// Query with nested relationships
const deals = await query`{
    deal(limit: ${ 50 }) {
        id,
        label,
        value,
        contact {
            id,
            firstName,
            lastName
        },
        company {
            id,
            companyName
        }
    }
}`;

Mutation Examples

// Insert
const newContact = await mutation`{
    insert_contact(objects: ${ [ { firstName: 'John', lastName: 'Doe' } ] }) {
        returning {
            id,
            firstName,
            lastName
        }
    }
}`;

// Update
const contactId = '123';
await mutation`{
    update_contact(id: ${ contactId }, firstName: "Jane", lastName: "Smith") {}
}`;

// Delete
const idsToDelete = [ '1', '2', '3' ];
await mutation`{
    delete_contact(id: ${ idsToDelete }) {}
}`;

// Connect relationships
await mutation`{
    connect_company_contact(objects: ${ [ { from: companyId, to: contactId } ] }) {}
}`;

// Disconnect relationships
await mutation`{
    disconnect_company_contact(objects: ${ [ { from: companyId, to: contactId } ] }) {}
}`;

serialize

Converts JavaScript values to Hermes query format. Used automatically in template literals but can be called directly for complex cases.

Type Handling

| JavaScript Type | Hermes Output | |-----------------|---------------| | null / undefined | null | | boolean | true / false | | number | 123 | | string | "quoted string" | | array | [item1, item2] | | object | {key: value} |

Examples

import { serialize } from '@gravityforms/request';

serialize( 'hello' );           // "hello"
serialize( 42 );                // 42
serialize( true );              // true
serialize( null );              // null
serialize( [ 1, 2, 3 ] );       // [1, 2, 3]
serialize( { name: 'John' } );  // {name: "John"}

args

Convenience function for building query/mutation argument strings from JavaScript objects. Combines serialize() and raw() for the common argument-building pattern.

Usage

import { args } from '@gravityforms/request';

// Instead of building argument strings manually:
const argsStr = Object.entries({ limit: 10, search: 'test' })
    .map(([k, v]) => `${k}: ${serialize(v)}`)
    .join(', ');
await query`{ contact(${ raw( argsStr ) }) { ... } }`;

// Use args() for cleaner syntax:
await query`{ contact(${ args({ limit: 10, search: 'test' }) }) { ... } }`;

raw

Marks a string for raw insertion without serialization. Use this when you've pre-built an argument string.

Problem

// Without raw() - becomes: pipeline("limit: 1") - WRONG!
const argsStr = 'limit: 1';
await query`{ pipeline(${ argsStr }) { id } }`;

Solution

import { raw } from '@gravityforms/request';

// With raw() - becomes: pipeline(limit: 1) - CORRECT!
const argsStr = 'limit: 1';
await query`{ pipeline(${ raw( argsStr ) }) { id } }`;

Common Use Cases

// Dynamic argument strings
const buildArgs = ( filters ) => {
    const parts = [];
    if ( filters.limit ) parts.push( `limit: ${ filters.limit }` );
    if ( filters.search ) parts.push( `search: ${ JSON.stringify( filters.search ) }` );
    return parts.join( ', ' );
};

const argsStr = buildArgs( { limit: 20, search: 'test' } );
await query`{ contact(${ raw( argsStr ) }) { id, firstName } }`;

// Dynamic field/type names
const objectType = 'contact';
await mutation`{
    delete_${ raw( objectType ) }(id: ${ ids }) {}
}`;

// Dynamic field names with serialize for values
const fieldName = 'firstName';
const value = 'John';
await mutation`{
    update_contact(id: ${ id }, ${ raw( fieldName ) }: ${ value }) {}
}`;

request (Default Export)

Configuration-based request handler. Requires endpoint configuration in gravityforms.config.js.

Configuration

In your project's gravityforms.config.js:

module.exports = {
    requestConfig: {
        endpoints: {
            get_entries: {
                path: '/wp-json/gf/v2/entries',
                rest_params: '',
                nonce: null,
            },
            save_form: {
                path: '/wp-json/gf/v2/forms',
                action: 'gf_save_form',
                nonce: null,
            },
        },
    },
};

Usage

import request from '@gravityforms/request';

// GET request
const entries = await request( 'get_entries', endpoints, {
    method: 'GET',
    params: { form_id: 1 },
} );

// POST request
const result = await request( 'save_form', endpoints, {
    method: 'POST',
    body: { title: 'My Form', fields: [ ... ] },
} );

React Integration

For React applications, use @gravityforms/react-utils which provides hooks and context:

import { useHermesTemplateContext, HermesTemplateProvider } from '@gravityforms/react-utils';

// In your app root
<HermesTemplateProvider
    defaultProps={ {
        endpoint: window.ajaxurl,
        queryAction: 'gcrm_hermes_query',
        mutationAction: 'gcrm_hermes_mutation',
        security: window.gcrm.nonce,
    } }
>
    <App />
</HermesTemplateProvider>

// In components
const MyComponent = () => {
    const { query, mutation, isLoading } = useHermesTemplateContext();

    const fetchContacts = async () => {
        const result = await query`{
            contact(limit: 10) { id, firstName, lastName }
        }`;
        return result?.data?.data?.contact;
    };
};

Error Handling

All request functions return errors in a consistent format:

const response = await post( { endpoint, body } );

if ( response.error ) {
    // Network error or exception
    console.error( response.error.message );
    console.error( response.error.detail ); // Contains endpoint, status, etc.
} else if ( ! response.data?.success ) {
    // Server returned an error response
    console.error( 'Request failed:', response.data );
} else {
    // Success
    console.log( 'Data:', response.data );
}

Best Practices

  1. Always use post for WordPress AJAX - handles FormData encoding automatically
  2. Include action and security nonce - required for WordPress AJAX handlers
  3. Use template literals for Hermes - clearer syntax that matches server expectations
  4. Use raw() for dynamic field names - prevents unwanted string quoting
  5. Check response?.data?.success - standard WordPress AJAX success pattern
  6. Provide user feedback - use snackbar or similar for success/error messages
import { post } from '@gravityforms/request';
import { useSnackbar } from '@gravityforms/components/react/admin/modules/SnackBar';

const addSnackbarMessage = useSnackbar();

const saveItem = async ( data ) => {
    const response = await post( {
        endpoint,
        body: {
            action: 'my_action',
            security: nonce,
            ...data,
        },
    } );

    if ( response?.data?.success ) {
        addSnackbarMessage( 'Saved successfully!' );
    } else {
        addSnackbarMessage( 'Failed to save', 'error' );
    }
};