@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-sdkQuick 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:
- Create an
/auth/callbackroute in your application - In the callback page, read the
tokenparameter from the URL query string - 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
tokenfrom 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 resultsskip(optional): Number of results to skipfields(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,emailentities[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 resultsskip(optional): Number of results to skipfields(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,emailentities[entityName].get(params)
Get a single entity by ID.
HTTP Details:
- Method:
GET - Path:
/api/v1/entities/{entityName}/{id} - Parameters:
id(required): Entity IDfields(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,emailentities[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 IDdata(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 includeidfor 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 pathmethod(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': UsesfetchAPI - Non-browser environment or other
responseTypevalues: Uses axios (default behavior)
Automatic Configuration:
When using fetch for streaming:
- Automatically includes
Authorizationheader fromlocalStorage.token(if available) - Automatically includes
Content-Type: application/jsonheader - Automatically includes
App-Hostheader with current origin - Automatically handles
baseURLfrom 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 nativeResponseobject - When using axios (default): Returns an
AxiosResponseobject
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, useswindow.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
urlis not provided or is undefined, the function returns without doing anything - For URLs containing
stripe.comwhen running in an MGX iframe (detected bywindow.namecontaining'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 iframeConfiguration
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);
}
}