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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@metagptx/web-sdk

v0.0.45

Published

TypeScript SDK for interacting with FuncSea API

Readme

FuncSea WebSDK

A TypeScript SDK for interacting with FuncSea API, providing modules for authentication, entity management, API calls, and integrations.

Installation

npm install @metagptx/web-sdk
# or
pnpm install @metagptx/web-sdk
# or
yarn add @metagptx/web-sdk

Quick Start

import { createClient } from '@metagptx/web-sdk';

// Create client instance (no configuration needed)
const client = createClient();

// Use the client
const user = await client.auth.me();

Modules

The SDK provides six main modules:

  • auth: User authentication operations
  • entities: Dynamic entity CRUD operations
  • apiCall: Custom API calls
  • integrations: Integration function invocations
  • frame: Frame communication operations for iframe/parent window messaging
  • utils: Utility functions for URL opening and window management

API Reference

Auth Module

Handles user authentication and session management.

Authentication Callback Setup

When using this SDK, your project needs to implement an /auth/callback route and page. This callback page is used to handle the authentication flow after a successful login.

Required Setup:

  1. Create an /auth/callback route in your application
  2. In the callback page, read the token parameter from the URL query string
  3. Call client.auth.login() to save the token to localStorage

Example Implementation:

// In your /auth/callback page component
import { useEffect } from 'react';

function AuthCallbackPage() {
  useEffect(() => {
    // This will automatically read the token from URL query string
    // and save it to localStorage
    client.auth.login().then((token) => {
      if (token) {
        // Token saved successfully, redirect to your app
        window.location.href = '/dashboard'; // or your desired route
      } else {
        // No token found, handle error
        console.error('No token found in URL');
      }
    });
  }, []);

  return <div>Processing authentication...</div>;
}

How it works:

  • After successful authentication, the user will be redirected to /auth/callback?token=xxx
  • The auth.login() method reads the token from the URL and stores it in localStorage
  • Once the token is saved, redirect the user to your application

auth.login()

Read the token from the URL query string and save it to localStorage.

HTTP Details:

  • Method: Client-side only (no HTTP request)
  • Parameters: None (automatically reads token from URL query string)

Returns: The token value if found, or null if not found.

Example:

const token = await client.auth.login();
if (token) {
  console.log('Token saved to localStorage');
}

auth.me()

Get current user information.

HTTP Details:

  • Method: GET
  • Path: /api/v1/auth/me
  • Parameters: None

Example:

const response = await client.auth.me();
console.log(response.data);

auth.logout()

Logout the current user.

HTTP Details:

  • Method: POST
  • Path: /api/v1/auth/logout
  • Parameters: None

Example:

await client.auth.logout();

auth.toLogin()

Redirect to the login page. This is a utility function that redirects the browser to the login URL with the current page as the redirect parameter.

Example:

client.auth.toLogin();

Entities Module

Provides dynamic CRUD operations for any entity type. Access entities using property syntax: client.entities.{entityName}.{operation}().

Note: The fields parameter (array) will be automatically converted to a comma-separated string, and the query parameter (object) will be automatically converted to a JSON string before sending to the API.

entities[entityName].query(params?)

Query entities with filtering, sorting, and pagination.

HTTP Details:

  • Method: GET
  • Path: /api/v1/entities/{entityName}
  • Parameters:
    • query (optional): Query conditions object (will be converted to JSON string)
    • sort (optional): Sort field and order (e.g., "-createdAt")
    • limit (optional): Maximum number of results
    • skip (optional): Number of results to skip
    • fields (optional): Array of fields to return (will be converted to comma-separated string)

Example:

const response = await client.entities.users.query({
  query: { status: 'active' },
  sort: '-createdAt',
  limit: 10,
  skip: 0,
  fields: ['id', 'name', 'email'],
});
// Actual API call: GET /api/v1/entities/users?query={"status":"active"}&sort=-createdAt&limit=10&skip=0&fields=id,name,email

entities[entityName].queryAll(params?)

Query all public entities with filtering, sorting, and pagination.

HTTP Details:

  • Method: GET
  • Path: /api/v1/entities/{entityName}/all
  • Parameters:
    • query (optional): Query conditions object (will be converted to JSON string)
    • sort (optional): Sort field and order (e.g., "-createdAt")
    • limit (optional): Maximum number of results
    • skip (optional): Number of results to skip
    • fields (optional): Array of fields to return (will be converted to comma-separated string)

Example:

const response = await client.entities.users.queryAll({
  query: { status: 'active' },
  sort: '-createdAt',
  limit: 10,
  skip: 0,
  fields: ['id', 'name', 'email'],
});
// Actual API call: GET /api/v1/entities/users/all?query={"status":"active"}&sort=-createdAt&limit=10&skip=0&fields=id,name,email

entities[entityName].get(params)

Get a single entity by ID.

HTTP Details:

  • Method: GET
  • Path: /api/v1/entities/{entityName}/{id}
  • Parameters:
    • id (required): Entity ID
    • fields (optional): Array of fields to return (will be converted to comma-separated string)

Example:

const response = await client.entities.users.get({
  id: '12345',
  fields: ['id', 'name', 'email'],
});
// Actual API call: GET /api/v1/entities/users/12345?fields=id,name,email

entities[entityName].create(params)

Create a new entity.

HTTP Details:

  • Method: POST
  • Path: /api/v1/entities/{entityName}
  • Body:
    • data (required): Entity data object

Example:

const response = await client.entities.users.create({
  data: {
    name: 'John Doe',
    email: '[email protected]',
    status: 'active',
  },
});

entities[entityName].update(params)

Update an existing entity.

HTTP Details:

  • Method: PUT
  • Path: /api/v1/entities/{entityName}/{id}
  • Body:
    • id (required): Entity ID
    • data (required): Updated entity data

Example:

const response = await client.entities.users.update({
  id: '12345',
  data: {
    name: 'Jane Doe',
    status: 'inactive',
  },
});

entities[entityName].delete(params)

Delete a single entity by ID.

HTTP Details:

  • Method: DELETE
  • Path: /api/v1/entities/{entityName}/{id}
  • Parameters:
    • id (required): Entity ID

Example:

await client.entities.users.delete({ id: '12345' });

entities[entityName].createBatch(params)

Create multiple entities in a single request.

HTTP Details:

  • Method: POST
  • Path: /api/v1/entities/{entityName}/batch
  • Body:
    • data (required): Array of entity data objects

Example:

const response = await client.entities.users.createBatch({
  data: [
    { name: 'John Doe', email: '[email protected]' },
    { name: 'Jane Smith', email: '[email protected]' },
  ],
});

entities[entityName].updateBatch(params)

Update multiple entities in a single request.

HTTP Details:

  • Method: PUT
  • Path: /api/v1/entities/{entityName}/batch
  • Body:
    • data (required): Array of entity data objects (must include id for each)

Example:

const response = await client.entities.users.updateBatch({
  data: [
    { id: '12345', status: 'active' },
    { id: '67890', status: 'inactive' },
  ],
});

entities[entityName].deleteBatch(params)

Delete multiple entities by their IDs.

HTTP Details:

  • Method: DELETE
  • Path: /api/v1/entities/{entityName}/batch
  • Body:
    • ids (required): Array of entity IDs

Example:

await client.entities.users.deleteBatch({
  ids: ['12345', '67890', '11111'],
});

API Call Module

Provides a flexible way to make custom API calls with any HTTP method.

apiCall.invoke(params)

Invoke a custom API call with specified method, URL, and data.

HTTP Details:

  • Method: Configurable (GET, POST, PUT, PATCH, DELETE, etc.)
  • Path: Configurable
  • Parameters:
    • url (required): API endpoint path
    • method (optional): HTTP method (defaults to 'GET')
    • data (optional): Request data (body for POST/PUT/PATCH, query params for GET/DELETE)
    • options (optional): Additional axios request options

Example:

// GET request with query parameters
const response = await client.apiCall.invoke({
  url: '/api/v1/custom/endpoint',
  method: 'GET',
  data: { filter: 'active' },
});

// POST request with object data
const response = await client.apiCall.invoke({
  url: '/api/v1/custom/action',
  method: 'POST',
  data: { key1: 'value1', key2: 'value2' },
  options: {
    headers: { 'X-Custom-Header': 'value' },
  },
});

// POST request with array data
const response = await client.apiCall.invoke({
  url: '/api/v1/custom/action',
  method: 'POST',
  data: [
    { key1: 'value1', key2: 'value2' },
    { key1: 'value3', key2: 'value4' }
  ],
  options: {
    headers: { 'X-Custom-Header': 'value' },
  },
});

Stream Response Type (Browser Only)

When making API calls in a browser environment with responseType: 'stream', the SDK automatically uses the native fetch API instead of axios to handle streaming responses more efficiently. This avoids potential performance issues with axios interceptors when processing streaming data.

Behavior:

  • Browser environment + responseType: 'stream': Uses fetch API
  • Non-browser environment or other responseType values: Uses axios (default behavior)

Automatic Configuration: When using fetch for streaming:

  • Automatically includes Authorization header from localStorage.token (if available)
  • Automatically includes Content-Type: application/json header
  • Automatically includes App-Host header with current origin
  • Automatically handles baseURL from axios instance configuration
  • Merges custom headers from options.headers
  • Automatically serializes request body for POST/PUT/PATCH methods

Return Value:

  • When using fetch (stream responseType in browser): Returns a native Response object
  • When using axios (default): Returns an AxiosResponse object

Example - Streaming Response:

// Stream response in browser - returns Response object
const response = await client.apiCall.invoke({
  url: '/api/v1/files/download',
  method: 'GET',
  options: {
    responseType: 'stream',
  },
});

// Access the ReadableStream from response.body
const reader = response.body?.getReader();
if (reader) {
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    // Process chunk: value is a Uint8Array
    console.log('Received chunk:', value);
  }
}

// Or convert to blob
const blob = await response.blob();
const url = URL.createObjectURL(blob);

Example - Regular Response (uses axios):

// Regular response - returns AxiosResponse object
const response = await client.apiCall.invoke({
  url: '/api/v1/custom/endpoint',
  method: 'GET',
  // responseType defaults to 'json' or undefined
});

// Access data via response.data (axios format)
console.log(response.data);

Note: In non-browser environments (e.g., Node.js), even with responseType: 'stream', the SDK will use axios to maintain consistency across environments.


Integrations Module

Provides dynamic access to integration functions. Access integrations using property syntax: client.integrations.{packageName}.{functionName}(params).

integrations.core[functionName](params?)

Invoke a core integration function.

HTTP Details:

  • Method: POST
  • Path: /api/integrations/core/{functionName}
  • Body:
    • payload (optional): Function payload data (object or FormData)
    • option (optional): Additional request options

Example:

const response = await client.integrations.core.sendEmail({
  payload: {
    to: '[email protected]',
    subject: 'Hello',
    body: 'Welcome!',
  },
});

integrations[packageName][functionName](params?)

Invoke a provider-specific integration function.

HTTP Details:

  • Method: POST
  • Path: /api/integrations/providers/{packageName}/{functionName}
  • Body:
    • payload (optional): Function payload data (object or FormData)
    • option (optional): Additional request options

Example:

// Regular JSON payload
const response = await client.integrations.stripe.createPayment({
  payload: {
    amount: 1000,
    currency: 'usd',
  },
});

// FormData payload for file uploads
const formData = new FormData();
formData.append('file', fileBlob);
formData.append('metadata', JSON.stringify({ key: 'value' }));

const response = await client.integrations.storage.uploadFile({
  payload: formData,
});

Frame Module

Provides utilities for communicating between iframe and parent window using postMessage API.

frame.createPage(path?)

Create a page by sending a 'mgx-create-page' message to the parent window.

Parameters:

  • path (optional): Page path to create. If not provided, uses window.location.pathname

Example:

// Create page with current path
client.frame.createPage();

// Create page with specific path
client.frame.createPage('/custom/path');

Utils Module

Provides utility functions for navigating to URLs.

utils.openUrl(url?)

Navigate to the given URL in the current window. For certain domains (like stripe.com) when running in an MGX iframe, this will send a postMessage to the parent window instead of navigating directly.

Parameters:

  • url (optional): The URL to navigate to (string or URL object)

Behavior:

  • If url is not provided or is undefined, the function returns without doing anything
  • For URLs containing stripe.com when running in an MGX iframe (detected by window.name containing 'devIframe'), the function sends a 'mgx-open-url' postMessage to the parent window instead of navigating
  • For other URLs or when not in an MGX iframe, the function navigates to the URL by setting window.location.href

Returns: undefined

Example:

// Navigate to a regular URL
client.utils.openUrl('https://example.com');

// Navigate using a URL object
const url = new URL('https://example.com/page');
client.utils.openUrl(url);

// Stripe URLs in MGX iframe will trigger postMessage instead
client.utils.openUrl('https://stripe.com/checkout'); // Sends postMessage to parent when in MGX iframe

// Stripe URLs outside MGX iframe will navigate normally
client.utils.openUrl('https://stripe.com/checkout'); // Navigates to URL when not in MGX iframe

Configuration

Client Configuration Options

In most cases, you don't need to pass any configuration:

// Default usage (recommended)
const client = createClient();

However, you can optionally customize the client behavior for advanced use cases:

const client = createClient({
  baseURL: '/custom-api',              // Custom base URL (defaults to '/')
  timeout: 30000,                      // Request timeout in milliseconds (defaults to 60000)
  headers: {                           // Custom headers
    'X-Custom-Header': 'value',
  },
  // Any other axios configuration options
});

Note: The baseURL and timeout options are reserved for future use or special deployment scenarios. Most users should rely on the default values.

Automatic 401 Handling

The SDK automatically handles 401 (Unauthorized) responses by redirecting to the login page. This behavior is built-in and requires no additional configuration.


TypeScript Support

The SDK is written in TypeScript and provides full type definitions. You can use generic types for typed responses:

interface User {
  id: string;
  name: string;
  email: string;
}

const response = await client.entities.users.get<User>({ id: '12345' });
const user: User = response.data;

Error Handling

All API calls return promises that may reject with an error. Always handle errors appropriately:

try {
  const response = await client.entities.users.get({ id: '12345' });
  console.log(response.data);
} catch (error) {
  if (error.response) {
    // Server responded with error status
    console.error('Error:', error.response.status, error.response.data);
  } else if (error.request) {
    // Request made but no response received
    console.error('No response received:', error.request);
  } else {
    // Error setting up the request
    console.error('Error:', error.message);
  }
}