Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
- [Using Abilities](docs/4.using-abilities.md)
- [REST API Reference](docs/5.rest-api.md)
- [Hooks](docs/6.hooks.md)
- [JavaScript/TypeScript Client](docs/7.javascript-client.md)
- [Contributing Guidelines](CONTRIBUTING.md)

## Inspiration
Expand Down
186 changes: 186 additions & 0 deletions docs/7.javascript-client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# 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()

Returns an array of all registered abilities (both server-side and client-side).

**Parameters:** None

**Returns:** `Promise<Array>` - Array of ability objects

**Example:**

```javascript
const abilities = await getAbilities();
console.log(`Found ${abilities.length} abilities`);

// List all abilities
abilities.forEach(ability => {
console.log(`${ability.name}: ${ability.description}`);
});
```

### 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);
}
```

### executeAbility(name, input)

Executes an ability with the provided input data.

**Parameters:**
- `name` (string) - The ability name
- `input` (object, 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:** `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
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:** `boolean` - True if the ability was found and removed

**Example:**

```javascript
// Unregister an ability
const wasRemoved = unregisterAbility('my-plugin/old-ability');
if (wasRemoved) {
console.log('Ability successfully removed');
}

// Check if ability is gone
const ability = await getAbility('my-plugin/old-ability');
console.log('Ability exists:', ability !== null);
```

## 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);
}
}
```