@wordpress/abilities 0.8.0 → 0.9.1-next.v.202604091042.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.9.0 (2026-04-01)
6
+
5
7
  ## 0.8.0 (2026-03-18)
6
8
 
7
9
  ## 0.7.0 (2026-03-04)
package/build/api.cjs.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/api.ts"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { dispatch, select } from '@wordpress/data';\nimport { sprintf } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport { store } from './store';\nimport type {\n\tAbility,\n\tAbilityCategory,\n\tAbilityCategoryArgs,\n\tAbilitiesQueryArgs,\n\tAbilityInput,\n\tAbilityOutput,\n} from './types';\nimport { validateValueFromSchema } from './validation';\n\n/**\n * Get all available abilities with optional filtering.\n *\n * @param args Optional query arguments to filter. Defaults to empty object.\n * @return Array of abilities.\n */\nexport function getAbilities( args: AbilitiesQueryArgs = {} ): Ability[] {\n\treturn select( store ).getAbilities( args );\n}\n\n/**\n * Get a specific ability by name.\n *\n * @param name The ability name.\n * @return The ability or undefined if not found.\n */\nexport function getAbility( name: string ): Ability | undefined {\n\treturn select( store ).getAbility( name );\n}\n\n/**\n * Get all available ability categories.\n *\n * @return Array of categories.\n */\nexport function getAbilityCategories(): AbilityCategory[] {\n\treturn select( store ).getAbilityCategories();\n}\n\n/**\n * Get a specific ability category by slug.\n *\n * @param slug The category slug.\n * @return The category or undefined if not found.\n */\nexport function getAbilityCategory(\n\tslug: string\n): AbilityCategory | undefined {\n\treturn select( store ).getAbilityCategory( slug );\n}\n\n/**\n * Register a client-side ability.\n *\n * Client abilities are executed locally in the browser and must include\n * a callback function. The ability will be validated by the store action,\n * and an error will be thrown if validation fails.\n *\n * The category must already be registered before registering abilities.\n *\n * @param ability The ability definition including callback.\n * @throws {Error} If the ability fails validation.\n *\n * @example\n * ```js\n * registerAbility({\n * name: 'my-plugin/navigate',\n * label: 'Navigate to URL',\n * description: 'Navigates to a URL within WordPress admin',\n * category: 'navigation',\n * input_schema: {\n * type: 'object',\n * properties: {\n * url: { type: 'string' }\n * },\n * required: ['url']\n * },\n * callback: async ({ url }) => {\n * window.location.href = url;\n * return { success: true };\n * }\n * });\n * ```\n */\nexport function registerAbility( ability: Ability ): void {\n\tdispatch( store ).registerAbility( ability );\n}\n\n/**\n * Unregister an ability from the store.\n *\n * Remove a client-side ability from the store.\n * Note: This will return an error for server-side abilities.\n *\n * @param name The ability name to unregister.\n */\nexport function unregisterAbility( name: string ): void {\n\tdispatch( store ).unregisterAbility( name );\n}\n\n/**\n * Register a client-side ability category.\n *\n * Categories registered on the client are stored alongside server-side categories\n * in the same store and can be used when registering client side abilities.\n * This is useful when registering client-side abilities that introduce new\n * categories not defined by the server.\n *\n * @param slug Category slug (lowercase alphanumeric with dashes only).\n * @param args Category arguments (label, description, optional meta).\n * @throws {Error} If the category fails validation.\n *\n * @example\n * ```js\n * // Register a new category for block editor abilities\n * registerAbilityCategory('block-editor', {\n * label: 'Block Editor',\n * description: 'Abilities for interacting with the WordPress block editor'\n * });\n *\n * // Then register abilities using this category\n * registerAbility({\n * name: 'my-plugin/insert-block',\n * label: 'Insert Block',\n * description: 'Inserts a block into the editor',\n * category: 'block-editor',\n * callback: async ({ blockType }) => {\n * // Implementation\n * return { success: true };\n * }\n * });\n * ```\n */\nexport function registerAbilityCategory(\n\tslug: string,\n\targs: AbilityCategoryArgs\n): void {\n\tdispatch( store ).registerAbilityCategory( slug, args );\n}\n\n/**\n * Unregister an ability category.\n *\n * Removes a category from the store.\n *\n * @param slug The category slug to unregister.\n *\n * @example\n * ```js\n * unregisterAbilityCategory('block-editor');\n * ```\n */\nexport function unregisterAbilityCategory( slug: string ): void {\n\tdispatch( store ).unregisterAbilityCategory( slug );\n}\n\n/**\n * Execute an ability.\n *\n * Executes abilities with validation for client-side abilities only.\n * Server abilities bypass validation as it's handled on the server.\n *\n * @param name The ability name.\n * @param input Optional input parameters for the ability.\n * @return Promise resolving to the ability execution result.\n * @throws Error if the ability is not found or execution fails.\n */\nexport async function executeAbility(\n\tname: string,\n\tinput?: AbilityInput\n): Promise< AbilityOutput > {\n\tconst ability = getAbility( name );\n\tif ( ! ability ) {\n\t\tthrow new Error( sprintf( 'Ability not found: %s', name ) );\n\t}\n\n\tif ( ! ability.callback ) {\n\t\tthrow new Error(\n\t\t\tsprintf(\n\t\t\t\t'Ability \"%s\" is missing callback. Please ensure the ability is properly registered.',\n\t\t\t\tability.name\n\t\t\t)\n\t\t);\n\t}\n\n\t// Check permission callback if defined\n\tif ( ability.permissionCallback ) {\n\t\tconst hasPermission = await ability.permissionCallback( input );\n\t\tif ( ! hasPermission ) {\n\t\t\tconst error = new Error(\n\t\t\t\tsprintf( 'Permission denied for ability: %s', ability.name )\n\t\t\t);\n\t\t\t( error as any ).code = 'ability_permission_denied';\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// Validate input\n\tif ( ability.input_schema ) {\n\t\tconst inputValidation = validateValueFromSchema(\n\t\t\tinput,\n\t\t\tability.input_schema,\n\t\t\t'input'\n\t\t);\n\t\tif ( inputValidation !== true ) {\n\t\t\tconst error = new Error(\n\t\t\t\tsprintf(\n\t\t\t\t\t'Ability \"%1$s\" has invalid input. Reason: %2$s',\n\t\t\t\t\tability.name,\n\t\t\t\t\tinputValidation\n\t\t\t\t)\n\t\t\t);\n\t\t\t( error as any ).code = 'ability_invalid_input';\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// Execute the ability\n\tlet result: AbilityOutput;\n\ttry {\n\t\tresult = await ability.callback( input );\n\t} catch ( error ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error( `Error executing ability ${ ability.name }:`, error );\n\t\tthrow error;\n\t}\n\n\t// Validate output\n\tif ( ability.output_schema ) {\n\t\tconst outputValidation = validateValueFromSchema(\n\t\t\tresult,\n\t\t\tability.output_schema,\n\t\t\t'output'\n\t\t);\n\t\tif ( outputValidation !== true ) {\n\t\t\tconst error = new Error(\n\t\t\t\tsprintf(\n\t\t\t\t\t'Ability \"%1$s\" has invalid output. Reason: %2$s',\n\t\t\t\t\tability.name,\n\t\t\t\t\toutputValidation\n\t\t\t\t)\n\t\t\t);\n\t\t\t( error as any ).code = 'ability_invalid_output';\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\treturn result;\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,kBAAiC;AACjC,kBAAwB;AAKxB,mBAAsB;AAStB,wBAAwC;AAQjC,SAAS,aAAc,OAA2B,CAAC,GAAe;AACxE,aAAO,oBAAQ,kBAAM,EAAE,aAAc,IAAK;AAC3C;AAQO,SAAS,WAAY,MAAoC;AAC/D,aAAO,oBAAQ,kBAAM,EAAE,WAAY,IAAK;AACzC;AAOO,SAAS,uBAA0C;AACzD,aAAO,oBAAQ,kBAAM,EAAE,qBAAqB;AAC7C;AAQO,SAAS,mBACf,MAC8B;AAC9B,aAAO,oBAAQ,kBAAM,EAAE,mBAAoB,IAAK;AACjD;AAmCO,SAAS,gBAAiB,SAAyB;AACzD,4BAAU,kBAAM,EAAE,gBAAiB,OAAQ;AAC5C;AAUO,SAAS,kBAAmB,MAAqB;AACvD,4BAAU,kBAAM,EAAE,kBAAmB,IAAK;AAC3C;AAmCO,SAAS,wBACf,MACA,MACO;AACP,4BAAU,kBAAM,EAAE,wBAAyB,MAAM,IAAK;AACvD;AAcO,SAAS,0BAA2B,MAAqB;AAC/D,4BAAU,kBAAM,EAAE,0BAA2B,IAAK;AACnD;AAaA,eAAsB,eACrB,MACA,OAC2B;AAC3B,QAAM,UAAU,WAAY,IAAK;AACjC,MAAK,CAAE,SAAU;AAChB,UAAM,IAAI,UAAO,qBAAS,yBAAyB,IAAK,CAAE;AAAA,EAC3D;AAEA,MAAK,CAAE,QAAQ,UAAW;AACzB,UAAM,IAAI;AAAA,UACT;AAAA,QACC;AAAA,QACA,QAAQ;AAAA,MACT;AAAA,IACD;AAAA,EACD;AAGA,MAAK,QAAQ,oBAAqB;AACjC,UAAM,gBAAgB,MAAM,QAAQ,mBAAoB,KAAM;AAC9D,QAAK,CAAE,eAAgB;AACtB,YAAM,QAAQ,IAAI;AAAA,YACjB,qBAAS,qCAAqC,QAAQ,IAAK;AAAA,MAC5D;AACA,MAAE,MAAe,OAAO;AACxB,YAAM;AAAA,IACP;AAAA,EACD;AAGA,MAAK,QAAQ,cAAe;AAC3B,UAAM,sBAAkB;AAAA,MACvB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACD;AACA,QAAK,oBAAoB,MAAO;AAC/B,YAAM,QAAQ,IAAI;AAAA,YACjB;AAAA,UACC;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,QACD;AAAA,MACD;AACA,MAAE,MAAe,OAAO;AACxB,YAAM;AAAA,IACP;AAAA,EACD;AAGA,MAAI;AACJ,MAAI;AACH,aAAS,MAAM,QAAQ,SAAU,KAAM;AAAA,EACxC,SAAU,OAAQ;AAEjB,YAAQ,MAAO,2BAA4B,QAAQ,IAAK,KAAK,KAAM;AACnE,UAAM;AAAA,EACP;AAGA,MAAK,QAAQ,eAAgB;AAC5B,UAAM,uBAAmB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACD;AACA,QAAK,qBAAqB,MAAO;AAChC,YAAM,QAAQ,IAAI;AAAA,YACjB;AAAA,UACC;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,QACD;AAAA,MACD;AACA,MAAE,MAAe,OAAO;AACxB,YAAM;AAAA,IACP;AAAA,EACD;AAEA,SAAO;AACR;",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { dispatch, select } from '@wordpress/data';\nimport { sprintf } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport { store } from './store';\nimport type {\n\tAbility,\n\tAbilityCategory,\n\tAbilityCategoryArgs,\n\tAbilitiesQueryArgs,\n\tAbilityInput,\n\tAbilityOutput,\n} from './types';\nimport { validateValueFromSchema } from './validation';\n\n/**\n * Get all available abilities with optional filtering.\n *\n * @param args Optional query arguments for filtering abilities.\n * @return Array of matching abilities.\n */\nexport function getAbilities( args: AbilitiesQueryArgs = {} ): Ability[] {\n\treturn select( store ).getAbilities( args );\n}\n\n/**\n * Get a specific ability by name.\n *\n * @param name The ability name.\n * @return The ability or undefined if not found.\n */\nexport function getAbility( name: string ): Ability | undefined {\n\treturn select( store ).getAbility( name );\n}\n\n/**\n * Get all available ability categories.\n *\n * @return Array of categories.\n */\nexport function getAbilityCategories(): AbilityCategory[] {\n\treturn select( store ).getAbilityCategories();\n}\n\n/**\n * Get a specific ability category by slug.\n *\n * @param slug The category slug.\n * @return The category or undefined if not found.\n */\nexport function getAbilityCategory(\n\tslug: string\n): AbilityCategory | undefined {\n\treturn select( store ).getAbilityCategory( slug );\n}\n\n/**\n * Register a client-side ability.\n *\n * Client-side abilities are executed locally in the browser and must include\n * a callback function. The ability's category must already be registered.\n *\n * @param ability The ability definition including callback.\n * @throws {Error} If the ability fails validation.\n *\n * @example\n * ```js\n * registerAbility({\n * name: 'my-plugin/navigate',\n * label: 'Navigate to URL',\n * description: 'Navigates to a URL within WordPress admin',\n * category: 'navigation',\n * input_schema: {\n * type: 'object',\n * properties: {\n * url: { type: 'string' }\n * },\n * required: ['url']\n * },\n * callback: async ({ url }) => {\n * window.location.href = url;\n * return { success: true };\n * }\n * });\n * ```\n */\nexport function registerAbility( ability: Ability ): void {\n\tdispatch( store ).registerAbility( ability );\n}\n\n/**\n * Unregister a client-side ability from the store.\n *\n * @param name The ability name to unregister.\n * @throws {Error} If the ability is server-side and cannot be unregistered.\n */\nexport function unregisterAbility( name: string ): void {\n\tdispatch( store ).unregisterAbility( name );\n}\n\n/**\n * Register a client-side ability category.\n *\n * Use this when registering client-side abilities that belong to a category\n * not already defined by the server. Client-side categories are stored\n * alongside server-side categories in the same store.\n *\n * @param slug Category slug (lowercase alphanumeric with dashes only).\n * @param args Category arguments (label, description, optional meta).\n * @throws {Error} If the category fails validation.\n *\n * @example\n * ```js\n * // Register a new category for block editor abilities\n * registerAbilityCategory('block-editor', {\n * label: 'Block Editor',\n * description: 'Abilities for interacting with the WordPress block editor'\n * });\n *\n * // Then register abilities using this category\n * registerAbility({\n * name: 'my-plugin/insert-block',\n * label: 'Insert Block',\n * description: 'Inserts a block into the editor',\n * category: 'block-editor',\n * callback: async ({ blockType }) => {\n * // Implementation\n * return { success: true };\n * }\n * });\n * ```\n */\nexport function registerAbilityCategory(\n\tslug: string,\n\targs: AbilityCategoryArgs\n): void {\n\tdispatch( store ).registerAbilityCategory( slug, args );\n}\n\n/**\n * Unregister an ability category.\n *\n * @param slug The category slug to unregister.\n *\n * @example\n * ```js\n * unregisterAbilityCategory('block-editor');\n * ```\n */\nexport function unregisterAbilityCategory( slug: string ): void {\n\tdispatch( store ).unregisterAbilityCategory( slug );\n}\n\n/**\n * Execute an ability.\n *\n * Validates input and output against their schemas when defined. For\n * server-side abilities, input is validated on the client first to avoid\n * unnecessary network roundtrips, then both input and output are validated on\n * the server. The client also re-validates the output to ensure data\n * compatibility between server and client.\n *\n * @param name The ability name.\n * @param input Optional input parameters for the ability.\n * @return Promise resolving to the ability execution result.\n * @throws {Error} If the ability is not found, permission is denied, input or output validation fails, or execution throws.\n */\nexport async function executeAbility(\n\tname: string,\n\tinput?: AbilityInput\n): Promise< AbilityOutput > {\n\tconst ability = getAbility( name );\n\tif ( ! ability ) {\n\t\tthrow new Error( sprintf( 'Ability not found: %s', name ) );\n\t}\n\n\tif ( ! ability.callback ) {\n\t\tthrow new Error(\n\t\t\tsprintf(\n\t\t\t\t'Ability \"%s\" is missing callback. Please ensure the ability is properly registered.',\n\t\t\t\tability.name\n\t\t\t)\n\t\t);\n\t}\n\n\t// Check permission callback if defined\n\tif ( ability.permissionCallback ) {\n\t\tconst hasPermission = await ability.permissionCallback( input );\n\t\tif ( ! hasPermission ) {\n\t\t\tconst error = new Error(\n\t\t\t\tsprintf( 'Permission denied for ability: %s', ability.name )\n\t\t\t);\n\t\t\t( error as any ).code = 'ability_permission_denied';\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// Validate input\n\tif ( ability.input_schema ) {\n\t\tconst inputValidation = validateValueFromSchema(\n\t\t\tinput,\n\t\t\tability.input_schema,\n\t\t\t'input'\n\t\t);\n\t\tif ( inputValidation !== true ) {\n\t\t\tconst error = new Error(\n\t\t\t\tsprintf(\n\t\t\t\t\t'Ability \"%1$s\" has invalid input. Reason: %2$s',\n\t\t\t\t\tability.name,\n\t\t\t\t\tinputValidation\n\t\t\t\t)\n\t\t\t);\n\t\t\t( error as any ).code = 'ability_invalid_input';\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// Execute the ability\n\tlet result: AbilityOutput;\n\ttry {\n\t\tresult = await ability.callback( input );\n\t} catch ( error ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error( `Error executing ability ${ ability.name }:`, error );\n\t\tthrow error;\n\t}\n\n\t// Validate output\n\tif ( ability.output_schema ) {\n\t\tconst outputValidation = validateValueFromSchema(\n\t\t\tresult,\n\t\t\tability.output_schema,\n\t\t\t'output'\n\t\t);\n\t\tif ( outputValidation !== true ) {\n\t\t\tconst error = new Error(\n\t\t\t\tsprintf(\n\t\t\t\t\t'Ability \"%1$s\" has invalid output. Reason: %2$s',\n\t\t\t\t\tability.name,\n\t\t\t\t\toutputValidation\n\t\t\t\t)\n\t\t\t);\n\t\t\t( error as any ).code = 'ability_invalid_output';\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\treturn result;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,kBAAiC;AACjC,kBAAwB;AAKxB,mBAAsB;AAStB,wBAAwC;AAQjC,SAAS,aAAc,OAA2B,CAAC,GAAe;AACxE,aAAO,oBAAQ,kBAAM,EAAE,aAAc,IAAK;AAC3C;AAQO,SAAS,WAAY,MAAoC;AAC/D,aAAO,oBAAQ,kBAAM,EAAE,WAAY,IAAK;AACzC;AAOO,SAAS,uBAA0C;AACzD,aAAO,oBAAQ,kBAAM,EAAE,qBAAqB;AAC7C;AAQO,SAAS,mBACf,MAC8B;AAC9B,aAAO,oBAAQ,kBAAM,EAAE,mBAAoB,IAAK;AACjD;AAgCO,SAAS,gBAAiB,SAAyB;AACzD,4BAAU,kBAAM,EAAE,gBAAiB,OAAQ;AAC5C;AAQO,SAAS,kBAAmB,MAAqB;AACvD,4BAAU,kBAAM,EAAE,kBAAmB,IAAK;AAC3C;AAkCO,SAAS,wBACf,MACA,MACO;AACP,4BAAU,kBAAM,EAAE,wBAAyB,MAAM,IAAK;AACvD;AAYO,SAAS,0BAA2B,MAAqB;AAC/D,4BAAU,kBAAM,EAAE,0BAA2B,IAAK;AACnD;AAgBA,eAAsB,eACrB,MACA,OAC2B;AAC3B,QAAM,UAAU,WAAY,IAAK;AACjC,MAAK,CAAE,SAAU;AAChB,UAAM,IAAI,UAAO,qBAAS,yBAAyB,IAAK,CAAE;AAAA,EAC3D;AAEA,MAAK,CAAE,QAAQ,UAAW;AACzB,UAAM,IAAI;AAAA,UACT;AAAA,QACC;AAAA,QACA,QAAQ;AAAA,MACT;AAAA,IACD;AAAA,EACD;AAGA,MAAK,QAAQ,oBAAqB;AACjC,UAAM,gBAAgB,MAAM,QAAQ,mBAAoB,KAAM;AAC9D,QAAK,CAAE,eAAgB;AACtB,YAAM,QAAQ,IAAI;AAAA,YACjB,qBAAS,qCAAqC,QAAQ,IAAK;AAAA,MAC5D;AACA,MAAE,MAAe,OAAO;AACxB,YAAM;AAAA,IACP;AAAA,EACD;AAGA,MAAK,QAAQ,cAAe;AAC3B,UAAM,sBAAkB;AAAA,MACvB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACD;AACA,QAAK,oBAAoB,MAAO;AAC/B,YAAM,QAAQ,IAAI;AAAA,YACjB;AAAA,UACC;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,QACD;AAAA,MACD;AACA,MAAE,MAAe,OAAO;AACxB,YAAM;AAAA,IACP;AAAA,EACD;AAGA,MAAI;AACJ,MAAI;AACH,aAAS,MAAM,QAAQ,SAAU,KAAM;AAAA,EACxC,SAAU,OAAQ;AAEjB,YAAQ,MAAO,2BAA4B,QAAQ,IAAK,KAAK,KAAM;AACnE,UAAM;AAAA,EACP;AAGA,MAAK,QAAQ,eAAgB;AAC5B,UAAM,uBAAmB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACD;AACA,QAAK,qBAAqB,MAAO;AAChC,YAAM,QAAQ,IAAI;AAAA,YACjB;AAAA,UACC;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,QACD;AAAA,MACD;AACA,MAAE,MAAe,OAAO;AACxB,YAAM;AAAA,IACP;AAAA,EACD;AAEA,SAAO;AACR;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/api.ts"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { dispatch, select } from '@wordpress/data';\nimport { sprintf } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport { store } from './store';\nimport type {\n\tAbility,\n\tAbilityCategory,\n\tAbilityCategoryArgs,\n\tAbilitiesQueryArgs,\n\tAbilityInput,\n\tAbilityOutput,\n} from './types';\nimport { validateValueFromSchema } from './validation';\n\n/**\n * Get all available abilities with optional filtering.\n *\n * @param args Optional query arguments to filter. Defaults to empty object.\n * @return Array of abilities.\n */\nexport function getAbilities( args: AbilitiesQueryArgs = {} ): Ability[] {\n\treturn select( store ).getAbilities( args );\n}\n\n/**\n * Get a specific ability by name.\n *\n * @param name The ability name.\n * @return The ability or undefined if not found.\n */\nexport function getAbility( name: string ): Ability | undefined {\n\treturn select( store ).getAbility( name );\n}\n\n/**\n * Get all available ability categories.\n *\n * @return Array of categories.\n */\nexport function getAbilityCategories(): AbilityCategory[] {\n\treturn select( store ).getAbilityCategories();\n}\n\n/**\n * Get a specific ability category by slug.\n *\n * @param slug The category slug.\n * @return The category or undefined if not found.\n */\nexport function getAbilityCategory(\n\tslug: string\n): AbilityCategory | undefined {\n\treturn select( store ).getAbilityCategory( slug );\n}\n\n/**\n * Register a client-side ability.\n *\n * Client abilities are executed locally in the browser and must include\n * a callback function. The ability will be validated by the store action,\n * and an error will be thrown if validation fails.\n *\n * The category must already be registered before registering abilities.\n *\n * @param ability The ability definition including callback.\n * @throws {Error} If the ability fails validation.\n *\n * @example\n * ```js\n * registerAbility({\n * name: 'my-plugin/navigate',\n * label: 'Navigate to URL',\n * description: 'Navigates to a URL within WordPress admin',\n * category: 'navigation',\n * input_schema: {\n * type: 'object',\n * properties: {\n * url: { type: 'string' }\n * },\n * required: ['url']\n * },\n * callback: async ({ url }) => {\n * window.location.href = url;\n * return { success: true };\n * }\n * });\n * ```\n */\nexport function registerAbility( ability: Ability ): void {\n\tdispatch( store ).registerAbility( ability );\n}\n\n/**\n * Unregister an ability from the store.\n *\n * Remove a client-side ability from the store.\n * Note: This will return an error for server-side abilities.\n *\n * @param name The ability name to unregister.\n */\nexport function unregisterAbility( name: string ): void {\n\tdispatch( store ).unregisterAbility( name );\n}\n\n/**\n * Register a client-side ability category.\n *\n * Categories registered on the client are stored alongside server-side categories\n * in the same store and can be used when registering client side abilities.\n * This is useful when registering client-side abilities that introduce new\n * categories not defined by the server.\n *\n * @param slug Category slug (lowercase alphanumeric with dashes only).\n * @param args Category arguments (label, description, optional meta).\n * @throws {Error} If the category fails validation.\n *\n * @example\n * ```js\n * // Register a new category for block editor abilities\n * registerAbilityCategory('block-editor', {\n * label: 'Block Editor',\n * description: 'Abilities for interacting with the WordPress block editor'\n * });\n *\n * // Then register abilities using this category\n * registerAbility({\n * name: 'my-plugin/insert-block',\n * label: 'Insert Block',\n * description: 'Inserts a block into the editor',\n * category: 'block-editor',\n * callback: async ({ blockType }) => {\n * // Implementation\n * return { success: true };\n * }\n * });\n * ```\n */\nexport function registerAbilityCategory(\n\tslug: string,\n\targs: AbilityCategoryArgs\n): void {\n\tdispatch( store ).registerAbilityCategory( slug, args );\n}\n\n/**\n * Unregister an ability category.\n *\n * Removes a category from the store.\n *\n * @param slug The category slug to unregister.\n *\n * @example\n * ```js\n * unregisterAbilityCategory('block-editor');\n * ```\n */\nexport function unregisterAbilityCategory( slug: string ): void {\n\tdispatch( store ).unregisterAbilityCategory( slug );\n}\n\n/**\n * Execute an ability.\n *\n * Executes abilities with validation for client-side abilities only.\n * Server abilities bypass validation as it's handled on the server.\n *\n * @param name The ability name.\n * @param input Optional input parameters for the ability.\n * @return Promise resolving to the ability execution result.\n * @throws Error if the ability is not found or execution fails.\n */\nexport async function executeAbility(\n\tname: string,\n\tinput?: AbilityInput\n): Promise< AbilityOutput > {\n\tconst ability = getAbility( name );\n\tif ( ! ability ) {\n\t\tthrow new Error( sprintf( 'Ability not found: %s', name ) );\n\t}\n\n\tif ( ! ability.callback ) {\n\t\tthrow new Error(\n\t\t\tsprintf(\n\t\t\t\t'Ability \"%s\" is missing callback. Please ensure the ability is properly registered.',\n\t\t\t\tability.name\n\t\t\t)\n\t\t);\n\t}\n\n\t// Check permission callback if defined\n\tif ( ability.permissionCallback ) {\n\t\tconst hasPermission = await ability.permissionCallback( input );\n\t\tif ( ! hasPermission ) {\n\t\t\tconst error = new Error(\n\t\t\t\tsprintf( 'Permission denied for ability: %s', ability.name )\n\t\t\t);\n\t\t\t( error as any ).code = 'ability_permission_denied';\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// Validate input\n\tif ( ability.input_schema ) {\n\t\tconst inputValidation = validateValueFromSchema(\n\t\t\tinput,\n\t\t\tability.input_schema,\n\t\t\t'input'\n\t\t);\n\t\tif ( inputValidation !== true ) {\n\t\t\tconst error = new Error(\n\t\t\t\tsprintf(\n\t\t\t\t\t'Ability \"%1$s\" has invalid input. Reason: %2$s',\n\t\t\t\t\tability.name,\n\t\t\t\t\tinputValidation\n\t\t\t\t)\n\t\t\t);\n\t\t\t( error as any ).code = 'ability_invalid_input';\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// Execute the ability\n\tlet result: AbilityOutput;\n\ttry {\n\t\tresult = await ability.callback( input );\n\t} catch ( error ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error( `Error executing ability ${ ability.name }:`, error );\n\t\tthrow error;\n\t}\n\n\t// Validate output\n\tif ( ability.output_schema ) {\n\t\tconst outputValidation = validateValueFromSchema(\n\t\t\tresult,\n\t\t\tability.output_schema,\n\t\t\t'output'\n\t\t);\n\t\tif ( outputValidation !== true ) {\n\t\t\tconst error = new Error(\n\t\t\t\tsprintf(\n\t\t\t\t\t'Ability \"%1$s\" has invalid output. Reason: %2$s',\n\t\t\t\t\tability.name,\n\t\t\t\t\toutputValidation\n\t\t\t\t)\n\t\t\t);\n\t\t\t( error as any ).code = 'ability_invalid_output';\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\treturn result;\n}\n"],
5
- "mappings": ";AAGA,SAAS,UAAU,cAAc;AACjC,SAAS,eAAe;AAKxB,SAAS,aAAa;AAStB,SAAS,+BAA+B;AAQjC,SAAS,aAAc,OAA2B,CAAC,GAAe;AACxE,SAAO,OAAQ,KAAM,EAAE,aAAc,IAAK;AAC3C;AAQO,SAAS,WAAY,MAAoC;AAC/D,SAAO,OAAQ,KAAM,EAAE,WAAY,IAAK;AACzC;AAOO,SAAS,uBAA0C;AACzD,SAAO,OAAQ,KAAM,EAAE,qBAAqB;AAC7C;AAQO,SAAS,mBACf,MAC8B;AAC9B,SAAO,OAAQ,KAAM,EAAE,mBAAoB,IAAK;AACjD;AAmCO,SAAS,gBAAiB,SAAyB;AACzD,WAAU,KAAM,EAAE,gBAAiB,OAAQ;AAC5C;AAUO,SAAS,kBAAmB,MAAqB;AACvD,WAAU,KAAM,EAAE,kBAAmB,IAAK;AAC3C;AAmCO,SAAS,wBACf,MACA,MACO;AACP,WAAU,KAAM,EAAE,wBAAyB,MAAM,IAAK;AACvD;AAcO,SAAS,0BAA2B,MAAqB;AAC/D,WAAU,KAAM,EAAE,0BAA2B,IAAK;AACnD;AAaA,eAAsB,eACrB,MACA,OAC2B;AAC3B,QAAM,UAAU,WAAY,IAAK;AACjC,MAAK,CAAE,SAAU;AAChB,UAAM,IAAI,MAAO,QAAS,yBAAyB,IAAK,CAAE;AAAA,EAC3D;AAEA,MAAK,CAAE,QAAQ,UAAW;AACzB,UAAM,IAAI;AAAA,MACT;AAAA,QACC;AAAA,QACA,QAAQ;AAAA,MACT;AAAA,IACD;AAAA,EACD;AAGA,MAAK,QAAQ,oBAAqB;AACjC,UAAM,gBAAgB,MAAM,QAAQ,mBAAoB,KAAM;AAC9D,QAAK,CAAE,eAAgB;AACtB,YAAM,QAAQ,IAAI;AAAA,QACjB,QAAS,qCAAqC,QAAQ,IAAK;AAAA,MAC5D;AACA,MAAE,MAAe,OAAO;AACxB,YAAM;AAAA,IACP;AAAA,EACD;AAGA,MAAK,QAAQ,cAAe;AAC3B,UAAM,kBAAkB;AAAA,MACvB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACD;AACA,QAAK,oBAAoB,MAAO;AAC/B,YAAM,QAAQ,IAAI;AAAA,QACjB;AAAA,UACC;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,QACD;AAAA,MACD;AACA,MAAE,MAAe,OAAO;AACxB,YAAM;AAAA,IACP;AAAA,EACD;AAGA,MAAI;AACJ,MAAI;AACH,aAAS,MAAM,QAAQ,SAAU,KAAM;AAAA,EACxC,SAAU,OAAQ;AAEjB,YAAQ,MAAO,2BAA4B,QAAQ,IAAK,KAAK,KAAM;AACnE,UAAM;AAAA,EACP;AAGA,MAAK,QAAQ,eAAgB;AAC5B,UAAM,mBAAmB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACD;AACA,QAAK,qBAAqB,MAAO;AAChC,YAAM,QAAQ,IAAI;AAAA,QACjB;AAAA,UACC;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,QACD;AAAA,MACD;AACA,MAAE,MAAe,OAAO;AACxB,YAAM;AAAA,IACP;AAAA,EACD;AAEA,SAAO;AACR;",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { dispatch, select } from '@wordpress/data';\nimport { sprintf } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport { store } from './store';\nimport type {\n\tAbility,\n\tAbilityCategory,\n\tAbilityCategoryArgs,\n\tAbilitiesQueryArgs,\n\tAbilityInput,\n\tAbilityOutput,\n} from './types';\nimport { validateValueFromSchema } from './validation';\n\n/**\n * Get all available abilities with optional filtering.\n *\n * @param args Optional query arguments for filtering abilities.\n * @return Array of matching abilities.\n */\nexport function getAbilities( args: AbilitiesQueryArgs = {} ): Ability[] {\n\treturn select( store ).getAbilities( args );\n}\n\n/**\n * Get a specific ability by name.\n *\n * @param name The ability name.\n * @return The ability or undefined if not found.\n */\nexport function getAbility( name: string ): Ability | undefined {\n\treturn select( store ).getAbility( name );\n}\n\n/**\n * Get all available ability categories.\n *\n * @return Array of categories.\n */\nexport function getAbilityCategories(): AbilityCategory[] {\n\treturn select( store ).getAbilityCategories();\n}\n\n/**\n * Get a specific ability category by slug.\n *\n * @param slug The category slug.\n * @return The category or undefined if not found.\n */\nexport function getAbilityCategory(\n\tslug: string\n): AbilityCategory | undefined {\n\treturn select( store ).getAbilityCategory( slug );\n}\n\n/**\n * Register a client-side ability.\n *\n * Client-side abilities are executed locally in the browser and must include\n * a callback function. The ability's category must already be registered.\n *\n * @param ability The ability definition including callback.\n * @throws {Error} If the ability fails validation.\n *\n * @example\n * ```js\n * registerAbility({\n * name: 'my-plugin/navigate',\n * label: 'Navigate to URL',\n * description: 'Navigates to a URL within WordPress admin',\n * category: 'navigation',\n * input_schema: {\n * type: 'object',\n * properties: {\n * url: { type: 'string' }\n * },\n * required: ['url']\n * },\n * callback: async ({ url }) => {\n * window.location.href = url;\n * return { success: true };\n * }\n * });\n * ```\n */\nexport function registerAbility( ability: Ability ): void {\n\tdispatch( store ).registerAbility( ability );\n}\n\n/**\n * Unregister a client-side ability from the store.\n *\n * @param name The ability name to unregister.\n * @throws {Error} If the ability is server-side and cannot be unregistered.\n */\nexport function unregisterAbility( name: string ): void {\n\tdispatch( store ).unregisterAbility( name );\n}\n\n/**\n * Register a client-side ability category.\n *\n * Use this when registering client-side abilities that belong to a category\n * not already defined by the server. Client-side categories are stored\n * alongside server-side categories in the same store.\n *\n * @param slug Category slug (lowercase alphanumeric with dashes only).\n * @param args Category arguments (label, description, optional meta).\n * @throws {Error} If the category fails validation.\n *\n * @example\n * ```js\n * // Register a new category for block editor abilities\n * registerAbilityCategory('block-editor', {\n * label: 'Block Editor',\n * description: 'Abilities for interacting with the WordPress block editor'\n * });\n *\n * // Then register abilities using this category\n * registerAbility({\n * name: 'my-plugin/insert-block',\n * label: 'Insert Block',\n * description: 'Inserts a block into the editor',\n * category: 'block-editor',\n * callback: async ({ blockType }) => {\n * // Implementation\n * return { success: true };\n * }\n * });\n * ```\n */\nexport function registerAbilityCategory(\n\tslug: string,\n\targs: AbilityCategoryArgs\n): void {\n\tdispatch( store ).registerAbilityCategory( slug, args );\n}\n\n/**\n * Unregister an ability category.\n *\n * @param slug The category slug to unregister.\n *\n * @example\n * ```js\n * unregisterAbilityCategory('block-editor');\n * ```\n */\nexport function unregisterAbilityCategory( slug: string ): void {\n\tdispatch( store ).unregisterAbilityCategory( slug );\n}\n\n/**\n * Execute an ability.\n *\n * Validates input and output against their schemas when defined. For\n * server-side abilities, input is validated on the client first to avoid\n * unnecessary network roundtrips, then both input and output are validated on\n * the server. The client also re-validates the output to ensure data\n * compatibility between server and client.\n *\n * @param name The ability name.\n * @param input Optional input parameters for the ability.\n * @return Promise resolving to the ability execution result.\n * @throws {Error} If the ability is not found, permission is denied, input or output validation fails, or execution throws.\n */\nexport async function executeAbility(\n\tname: string,\n\tinput?: AbilityInput\n): Promise< AbilityOutput > {\n\tconst ability = getAbility( name );\n\tif ( ! ability ) {\n\t\tthrow new Error( sprintf( 'Ability not found: %s', name ) );\n\t}\n\n\tif ( ! ability.callback ) {\n\t\tthrow new Error(\n\t\t\tsprintf(\n\t\t\t\t'Ability \"%s\" is missing callback. Please ensure the ability is properly registered.',\n\t\t\t\tability.name\n\t\t\t)\n\t\t);\n\t}\n\n\t// Check permission callback if defined\n\tif ( ability.permissionCallback ) {\n\t\tconst hasPermission = await ability.permissionCallback( input );\n\t\tif ( ! hasPermission ) {\n\t\t\tconst error = new Error(\n\t\t\t\tsprintf( 'Permission denied for ability: %s', ability.name )\n\t\t\t);\n\t\t\t( error as any ).code = 'ability_permission_denied';\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// Validate input\n\tif ( ability.input_schema ) {\n\t\tconst inputValidation = validateValueFromSchema(\n\t\t\tinput,\n\t\t\tability.input_schema,\n\t\t\t'input'\n\t\t);\n\t\tif ( inputValidation !== true ) {\n\t\t\tconst error = new Error(\n\t\t\t\tsprintf(\n\t\t\t\t\t'Ability \"%1$s\" has invalid input. Reason: %2$s',\n\t\t\t\t\tability.name,\n\t\t\t\t\tinputValidation\n\t\t\t\t)\n\t\t\t);\n\t\t\t( error as any ).code = 'ability_invalid_input';\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// Execute the ability\n\tlet result: AbilityOutput;\n\ttry {\n\t\tresult = await ability.callback( input );\n\t} catch ( error ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error( `Error executing ability ${ ability.name }:`, error );\n\t\tthrow error;\n\t}\n\n\t// Validate output\n\tif ( ability.output_schema ) {\n\t\tconst outputValidation = validateValueFromSchema(\n\t\t\tresult,\n\t\t\tability.output_schema,\n\t\t\t'output'\n\t\t);\n\t\tif ( outputValidation !== true ) {\n\t\t\tconst error = new Error(\n\t\t\t\tsprintf(\n\t\t\t\t\t'Ability \"%1$s\" has invalid output. Reason: %2$s',\n\t\t\t\t\tability.name,\n\t\t\t\t\toutputValidation\n\t\t\t\t)\n\t\t\t);\n\t\t\t( error as any ).code = 'ability_invalid_output';\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\treturn result;\n}\n"],
5
+ "mappings": ";AAGA,SAAS,UAAU,cAAc;AACjC,SAAS,eAAe;AAKxB,SAAS,aAAa;AAStB,SAAS,+BAA+B;AAQjC,SAAS,aAAc,OAA2B,CAAC,GAAe;AACxE,SAAO,OAAQ,KAAM,EAAE,aAAc,IAAK;AAC3C;AAQO,SAAS,WAAY,MAAoC;AAC/D,SAAO,OAAQ,KAAM,EAAE,WAAY,IAAK;AACzC;AAOO,SAAS,uBAA0C;AACzD,SAAO,OAAQ,KAAM,EAAE,qBAAqB;AAC7C;AAQO,SAAS,mBACf,MAC8B;AAC9B,SAAO,OAAQ,KAAM,EAAE,mBAAoB,IAAK;AACjD;AAgCO,SAAS,gBAAiB,SAAyB;AACzD,WAAU,KAAM,EAAE,gBAAiB,OAAQ;AAC5C;AAQO,SAAS,kBAAmB,MAAqB;AACvD,WAAU,KAAM,EAAE,kBAAmB,IAAK;AAC3C;AAkCO,SAAS,wBACf,MACA,MACO;AACP,WAAU,KAAM,EAAE,wBAAyB,MAAM,IAAK;AACvD;AAYO,SAAS,0BAA2B,MAAqB;AAC/D,WAAU,KAAM,EAAE,0BAA2B,IAAK;AACnD;AAgBA,eAAsB,eACrB,MACA,OAC2B;AAC3B,QAAM,UAAU,WAAY,IAAK;AACjC,MAAK,CAAE,SAAU;AAChB,UAAM,IAAI,MAAO,QAAS,yBAAyB,IAAK,CAAE;AAAA,EAC3D;AAEA,MAAK,CAAE,QAAQ,UAAW;AACzB,UAAM,IAAI;AAAA,MACT;AAAA,QACC;AAAA,QACA,QAAQ;AAAA,MACT;AAAA,IACD;AAAA,EACD;AAGA,MAAK,QAAQ,oBAAqB;AACjC,UAAM,gBAAgB,MAAM,QAAQ,mBAAoB,KAAM;AAC9D,QAAK,CAAE,eAAgB;AACtB,YAAM,QAAQ,IAAI;AAAA,QACjB,QAAS,qCAAqC,QAAQ,IAAK;AAAA,MAC5D;AACA,MAAE,MAAe,OAAO;AACxB,YAAM;AAAA,IACP;AAAA,EACD;AAGA,MAAK,QAAQ,cAAe;AAC3B,UAAM,kBAAkB;AAAA,MACvB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACD;AACA,QAAK,oBAAoB,MAAO;AAC/B,YAAM,QAAQ,IAAI;AAAA,QACjB;AAAA,UACC;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,QACD;AAAA,MACD;AACA,MAAE,MAAe,OAAO;AACxB,YAAM;AAAA,IACP;AAAA,EACD;AAGA,MAAI;AACJ,MAAI;AACH,aAAS,MAAM,QAAQ,SAAU,KAAM;AAAA,EACxC,SAAU,OAAQ;AAEjB,YAAQ,MAAO,2BAA4B,QAAQ,IAAK,KAAK,KAAM;AACnE,UAAM;AAAA,EACP;AAGA,MAAK,QAAQ,eAAgB;AAC5B,UAAM,mBAAmB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACD;AACA,QAAK,qBAAqB,MAAO;AAChC,YAAM,QAAQ,IAAI;AAAA,QACjB;AAAA,UACC;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,QACD;AAAA,MACD;AACA,MAAE,MAAe,OAAO;AACxB,YAAM;AAAA,IACP;AAAA,EACD;AAEA,SAAO;AACR;",
6
6
  "names": []
7
7
  }
@@ -2,8 +2,8 @@ import type { Ability, AbilityCategory, AbilityCategoryArgs, AbilitiesQueryArgs,
2
2
  /**
3
3
  * Get all available abilities with optional filtering.
4
4
  *
5
- * @param args Optional query arguments to filter. Defaults to empty object.
6
- * @return Array of abilities.
5
+ * @param args Optional query arguments for filtering abilities.
6
+ * @return Array of matching abilities.
7
7
  */
8
8
  export declare function getAbilities(args?: AbilitiesQueryArgs): Ability[];
9
9
  /**
@@ -29,11 +29,8 @@ export declare function getAbilityCategory(slug: string): AbilityCategory | unde
29
29
  /**
30
30
  * Register a client-side ability.
31
31
  *
32
- * Client abilities are executed locally in the browser and must include
33
- * a callback function. The ability will be validated by the store action,
34
- * and an error will be thrown if validation fails.
35
- *
36
- * The category must already be registered before registering abilities.
32
+ * Client-side abilities are executed locally in the browser and must include
33
+ * a callback function. The ability's category must already be registered.
37
34
  *
38
35
  * @param ability The ability definition including callback.
39
36
  * @throws {Error} If the ability fails validation.
@@ -61,21 +58,18 @@ export declare function getAbilityCategory(slug: string): AbilityCategory | unde
61
58
  */
62
59
  export declare function registerAbility(ability: Ability): void;
63
60
  /**
64
- * Unregister an ability from the store.
65
- *
66
- * Remove a client-side ability from the store.
67
- * Note: This will return an error for server-side abilities.
61
+ * Unregister a client-side ability from the store.
68
62
  *
69
- * @param name The ability name to unregister.
63
+ * @param name The ability name to unregister.
64
+ * @throws {Error} If the ability is server-side and cannot be unregistered.
70
65
  */
71
66
  export declare function unregisterAbility(name: string): void;
72
67
  /**
73
68
  * Register a client-side ability category.
74
69
  *
75
- * Categories registered on the client are stored alongside server-side categories
76
- * in the same store and can be used when registering client side abilities.
77
- * This is useful when registering client-side abilities that introduce new
78
- * categories not defined by the server.
70
+ * Use this when registering client-side abilities that belong to a category
71
+ * not already defined by the server. Client-side categories are stored
72
+ * alongside server-side categories in the same store.
79
73
  *
80
74
  * @param slug Category slug (lowercase alphanumeric with dashes only).
81
75
  * @param args Category arguments (label, description, optional meta).
@@ -106,8 +100,6 @@ export declare function registerAbilityCategory(slug: string, args: AbilityCateg
106
100
  /**
107
101
  * Unregister an ability category.
108
102
  *
109
- * Removes a category from the store.
110
- *
111
103
  * @param slug The category slug to unregister.
112
104
  *
113
105
  * @example
@@ -119,13 +111,16 @@ export declare function unregisterAbilityCategory(slug: string): void;
119
111
  /**
120
112
  * Execute an ability.
121
113
  *
122
- * Executes abilities with validation for client-side abilities only.
123
- * Server abilities bypass validation as it's handled on the server.
114
+ * Validates input and output against their schemas when defined. For
115
+ * server-side abilities, input is validated on the client first to avoid
116
+ * unnecessary network roundtrips, then both input and output are validated on
117
+ * the server. The client also re-validates the output to ensure data
118
+ * compatibility between server and client.
124
119
  *
125
- * @param name The ability name.
126
- * @param input Optional input parameters for the ability.
120
+ * @param name The ability name.
121
+ * @param input Optional input parameters for the ability.
127
122
  * @return Promise resolving to the ability execution result.
128
- * @throws Error if the ability is not found or execution fails.
123
+ * @throws {Error} If the ability is not found, permission is denied, input or output validation fails, or execution throws.
129
124
  */
130
125
  export declare function executeAbility(name: string, input?: AbilityInput): Promise<AbilityOutput>;
131
126
  //# sourceMappingURL=api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACX,OAAO,EACP,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,MAAM,SAAS,CAAC;AAGjB;;;;;GAKG;AACH,wBAAgB,YAAY,CAAE,IAAI,GAAE,kBAAuB,GAAI,OAAO,EAAE,CAEvE;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAE,IAAI,EAAE,MAAM,GAAI,OAAO,GAAG,SAAS,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,eAAe,EAAE,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CACjC,IAAI,EAAE,MAAM,GACV,eAAe,GAAG,SAAS,CAE7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,eAAe,CAAE,OAAO,EAAE,OAAO,GAAI,IAAI,CAExD;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAE,IAAI,EAAE,MAAM,GAAI,IAAI,CAEtD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,uBAAuB,CACtC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,mBAAmB,GACvB,IAAI,CAEN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAE,IAAI,EAAE,MAAM,GAAI,IAAI,CAE9D;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CACnC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,YAAY,GAClB,OAAO,CAAE,aAAa,CAAE,CA8E1B"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACX,OAAO,EACP,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,MAAM,SAAS,CAAC;AAGjB;;;;;GAKG;AACH,wBAAgB,YAAY,CAAE,IAAI,GAAE,kBAAuB,GAAI,OAAO,EAAE,CAEvE;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAE,IAAI,EAAE,MAAM,GAAI,OAAO,GAAG,SAAS,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,eAAe,EAAE,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CACjC,IAAI,EAAE,MAAM,GACV,eAAe,GAAG,SAAS,CAE7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,eAAe,CAAE,OAAO,EAAE,OAAO,GAAI,IAAI,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAE,IAAI,EAAE,MAAM,GAAI,IAAI,CAEtD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,uBAAuB,CACtC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,mBAAmB,GACvB,IAAI,CAEN;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAE,IAAI,EAAE,MAAM,GAAI,IAAI,CAE9D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,cAAc,CACnC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,YAAY,GAClB,OAAO,CAAE,aAAa,CAAE,CA8E1B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/abilities",
3
- "version": "0.8.0",
3
+ "version": "0.9.1-next.v.202604091042.0+668146787",
4
4
  "description": "JavaScript client for WordPress Abilities API.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -45,8 +45,8 @@
45
45
  },
46
46
  "types": "build-types",
47
47
  "dependencies": {
48
- "@wordpress/data": "^10.42.0",
49
- "@wordpress/i18n": "^6.15.0",
48
+ "@wordpress/data": "^10.43.1-next.v.202604091042.0+668146787",
49
+ "@wordpress/i18n": "^6.17.1-next.v.202604091042.0+668146787",
50
50
  "ajv": "^8.17.1",
51
51
  "ajv-draft-04": "^1.0.0",
52
52
  "ajv-formats": "^3.0.1"
@@ -54,5 +54,5 @@
54
54
  "publishConfig": {
55
55
  "access": "public"
56
56
  },
57
- "gitHead": "c20787b1778ae64c2db65643b1c236309d68e6ba"
57
+ "gitHead": "73606df74f1c38a084bfa5db97205259ef817593"
58
58
  }
package/src/api.ts CHANGED
@@ -21,8 +21,8 @@ import { validateValueFromSchema } from './validation';
21
21
  /**
22
22
  * Get all available abilities with optional filtering.
23
23
  *
24
- * @param args Optional query arguments to filter. Defaults to empty object.
25
- * @return Array of abilities.
24
+ * @param args Optional query arguments for filtering abilities.
25
+ * @return Array of matching abilities.
26
26
  */
27
27
  export function getAbilities( args: AbilitiesQueryArgs = {} ): Ability[] {
28
28
  return select( store ).getAbilities( args );
@@ -62,11 +62,8 @@ export function getAbilityCategory(
62
62
  /**
63
63
  * Register a client-side ability.
64
64
  *
65
- * Client abilities are executed locally in the browser and must include
66
- * a callback function. The ability will be validated by the store action,
67
- * and an error will be thrown if validation fails.
68
- *
69
- * The category must already be registered before registering abilities.
65
+ * Client-side abilities are executed locally in the browser and must include
66
+ * a callback function. The ability's category must already be registered.
70
67
  *
71
68
  * @param ability The ability definition including callback.
72
69
  * @throws {Error} If the ability fails validation.
@@ -97,12 +94,10 @@ export function registerAbility( ability: Ability ): void {
97
94
  }
98
95
 
99
96
  /**
100
- * Unregister an ability from the store.
101
- *
102
- * Remove a client-side ability from the store.
103
- * Note: This will return an error for server-side abilities.
97
+ * Unregister a client-side ability from the store.
104
98
  *
105
- * @param name The ability name to unregister.
99
+ * @param name The ability name to unregister.
100
+ * @throws {Error} If the ability is server-side and cannot be unregistered.
106
101
  */
107
102
  export function unregisterAbility( name: string ): void {
108
103
  dispatch( store ).unregisterAbility( name );
@@ -111,10 +106,9 @@ export function unregisterAbility( name: string ): void {
111
106
  /**
112
107
  * Register a client-side ability category.
113
108
  *
114
- * Categories registered on the client are stored alongside server-side categories
115
- * in the same store and can be used when registering client side abilities.
116
- * This is useful when registering client-side abilities that introduce new
117
- * categories not defined by the server.
109
+ * Use this when registering client-side abilities that belong to a category
110
+ * not already defined by the server. Client-side categories are stored
111
+ * alongside server-side categories in the same store.
118
112
  *
119
113
  * @param slug Category slug (lowercase alphanumeric with dashes only).
120
114
  * @param args Category arguments (label, description, optional meta).
@@ -151,8 +145,6 @@ export function registerAbilityCategory(
151
145
  /**
152
146
  * Unregister an ability category.
153
147
  *
154
- * Removes a category from the store.
155
- *
156
148
  * @param slug The category slug to unregister.
157
149
  *
158
150
  * @example
@@ -167,13 +159,16 @@ export function unregisterAbilityCategory( slug: string ): void {
167
159
  /**
168
160
  * Execute an ability.
169
161
  *
170
- * Executes abilities with validation for client-side abilities only.
171
- * Server abilities bypass validation as it's handled on the server.
162
+ * Validates input and output against their schemas when defined. For
163
+ * server-side abilities, input is validated on the client first to avoid
164
+ * unnecessary network roundtrips, then both input and output are validated on
165
+ * the server. The client also re-validates the output to ensure data
166
+ * compatibility between server and client.
172
167
  *
173
- * @param name The ability name.
174
- * @param input Optional input parameters for the ability.
168
+ * @param name The ability name.
169
+ * @param input Optional input parameters for the ability.
175
170
  * @return Promise resolving to the ability execution result.
176
- * @throws Error if the ability is not found or execution fails.
171
+ * @throws {Error} If the ability is not found, permission is denied, input or output validation fails, or execution throws.
177
172
  */
178
173
  export async function executeAbility(
179
174
  name: string,