Files
2025-11-29 18:25:36 +08:00

299 lines
7.5 KiB
Markdown

# 7. JavaScript/TypeScript Client
The JavaScript client provides an interface for discovering and executing WordPress Abilities from the browser.
## Overview
The JavaScript client enables frontend code to interact with the Abilities API system. It can:
- Discover all registered abilities on your WordPress site
- Execute server-side PHP abilities
- Register and execute client-side JavaScript abilities
You can read more about installation and setup in the [package readme](../packages/client/README.md).
## Core API Functions
### `getAbilities( args = {} )`
Returns an array of all registered abilities (both server-side and client-side).
**Parameters:** `args` (object, optional) - Query arguments to filter abilities. Supported arguments:
- `category` (string) - Filter abilities by category slug
**Returns:** `Promise<Array>` - Array of ability objects
**Example:**
```javascript
import { getAbilities } from `@wordpress/abilities`;
const abilities = await getAbilities();
console.log(`Found ${abilities.length} abilities`);
// List all abilities
abilities.forEach(ability => {
console.log(`${ability.name}: ${ability.description}`);
});
// Get abilities in a specific category
const dataAbilities = await getAbilities( { category: 'data-retrieval' } );
console.log( `Found ${ dataAbilities.length } data retrieval abilities` );
```
### getAbility( name )
Retrieves a specific ability by name.
**Parameters:**
- `name` (string) - The ability name (e.g., 'my-plugin/get-posts')
**Returns:** `Promise<Object|null>` - The ability object or null if not found
**Example:**
```javascript
const ability = await getAbility( 'my-plugin/get-site-info' );
if ( ability ) {
console.log( 'Label:', ability.label );
console.log( 'Description:', ability.description );
console.log( 'Input Schema:', ability.input_schema );
}
```
### `getAbilityCategories()`
Returns an array of all registered ability categories.
**Parameters:** None
**Returns:** `Promise<Array>` - Array of category objects
**Example:**
```javascript
const categories = await getAbilityCategories();
console.log( `Found ${ categories.length } categories` );
// List all categories
categories.forEach( ( category ) => {
console.log( `${ category.label }: ${ category.description }` );
} );
```
### `getAbilityCategory( slug )`
Retrieves a specific category by slug.
**Parameters:**
- `slug` (string) - The category slug (e.g., 'data-retrieval')
**Returns:** `Promise<Object|null>` - The category object or null if not found
**Example:**
```javascript
const category = await getAbilityCategory( 'data-retrieval' );
if ( category ) {
console.log( 'Label:', category.label );
console.log( 'Description:', category.description );
}
```
### `executeAbility( name, input = null )`
Executes an ability with the provided input data.
**Parameters:**
- `name` (string) - The ability name
- `input` (any, optional) - Input data for the ability
**Returns:** `Promise<any>` - The ability's output
**Example:**
```javascript
// Execute without input
const siteTitle = await executeAbility( 'my-plugin/get-site-title' );
console.log( 'Site:', siteTitle );
// Execute with input parameters
const posts = await executeAbility( 'my-plugin/get-posts', {
category: 'news',
limit: 5,
} );
posts.forEach( ( post ) => console.log( post.title ) );
```
### `registerAbility( ability )`
Registers a client-side ability that runs in the browser.
**Parameters:**
- `ability` (object) - The ability configuration object
**Returns:** `Promise<void>`
**Example:**
```javascript
// showNotification function
const showNotification = ( message ) => {
new Notification( message );
return { success: true, displayed: message };
};
// Register a notification ability which calls the showNotification function
await registerAbility( {
name: 'my-plugin/show-notification',
label: 'Show Notification',
description: 'Display a notification message to the user',
input_schema: {
type: 'object',
properties: {
message: { type: 'string' },
type: { type: 'string', enum: [ 'success', 'error', 'warning', 'info' ] },
},
required: [ 'message' ],
},
callback: async ( { message, type = 'info' } ) => {
// Show browser notification
if ( ! ( 'Notification' in window ) ) {
alert( 'This browser does not support desktop notification' );
return {
success: false,
error: 'Browser does not support notifications',
};
}
if ( Notification.permission !== 'granted' ) {
Notification.requestPermission().then( ( permission ) => {
if ( permission === 'granted' ) {
return showNotification( message );
}
} );
}
return showNotification( message );
},
permissionCallback: () => {
return !! wp.data.select( 'core' ).getCurrentUser();
},
} );
// Use the registered ability
const result = await executeAbility( 'my-plugin/show-notification', {
message: 'Hello World!',
type: 'success',
} );
```
### `unregisterAbility( name )`
Removes a previously registered client-side ability.
**Parameters:**
- `name` (string) - The ability name to unregister
**Returns:** `void`
**Example:**
```javascript
// Unregister an ability
unregisterAbility( 'my-plugin/old-ability' );
```
### `registerAbilityCategory( slug, args )`
Registers a client-side ability category. This is useful when registering client-side abilities that introduce new categories not defined by the server.
**Parameters:**
- `slug` (string) - The category slug (lowercase alphanumeric with dashes only)
- `args` (object) - Category configuration object
- `label` (string) - Human-readable label for the category
- `description` (string) - Detailed description of the category
- `meta` (object, optional) - Optional metadata about the category
**Returns:** `Promise<void>`
**Example:**
```javascript
// Register a new category
await registerAbilityCategory( 'block-editor', {
label: 'Block Editor',
description: 'Abilities for interacting with the WordPress block editor',
} );
// Register a category with metadata
await registerAbilityCategory( 'custom-category', {
label: 'Custom Category',
description: 'A category for custom abilities',
meta: {
priority: 'high',
icon: 'dashicons-admin-customizer',
},
} );
// Then register abilities using the new category
await registerAbility( {
name: 'my-plugin/insert-block',
label: 'Insert Block',
description: 'Inserts a block into the editor',
category: 'block-editor', // Uses the client-registered category
callback: async ( { blockType } ) => {
// Implementation
return { success: true };
},
} );
```
### `unregisterAbilityCategory( slug )`
Removes a previously registered client-side category.
**Parameters:**
- `slug` (string) - The category slug to unregister
**Returns:** `void`
**Example:**
```javascript
// Unregister a category
unregisterAbilityCategory( 'block-editor' );
```
## Error Handling
All functions return promises that may reject with specific error codes:
```javascript
try {
const result = await executeAbility( 'my-plugin/restricted-action', input );
console.log( 'Success:', result );
} catch ( error ) {
switch ( error.code ) {
case 'ability_permission_denied':
console.error( 'Permission denied:', error.message );
break;
case 'ability_invalid_input':
console.error( 'Invalid input:', error.message );
break;
case 'rest_ability_not_found':
console.error( 'Ability not found:', error.message );
break;
default:
console.error( 'Execution failed:', error.message );
}
}
```