@wordpress/core-abilities 0.11.0 → 0.12.1
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/README.md +6 -14
- package/build/index.cjs +11 -6
- package/build/index.cjs.map +2 -2
- package/build-module/index.mjs +10 -5
- package/build-module/index.mjs.map +2 -2
- package/build-types/index.d.ts +8 -1
- package/build-types/index.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/index.ts +15 -8
package/README.md
CHANGED
|
@@ -16,26 +16,18 @@ _This package assumes that your code will run in an ES2015+ environment. If you'
|
|
|
16
16
|
|
|
17
17
|
## Usage
|
|
18
18
|
|
|
19
|
-
This package is designed to be loaded as a script module on WordPress admin pages.
|
|
19
|
+
This package is designed to be loaded as a script module on WordPress admin pages. It exposes an `initialize()` function that, on first call:
|
|
20
20
|
|
|
21
|
-
1. Fetches all ability categories from `/wp-abilities/v1/categories`
|
|
22
|
-
2.
|
|
23
|
-
3. Fetches all abilities from `/wp-abilities/v1/abilities`
|
|
24
|
-
4. Registers them with a `callback` that handles execution via REST API
|
|
21
|
+
1. Fetches all ability categories from `/wp-abilities/v1/categories` and registers them with `@wordpress/abilities`
|
|
22
|
+
2. Fetches all abilities from `/wp-abilities/v1/abilities` and registers them with a `callback` that handles execution via REST API
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
Initialization is lazy: importing the package does not trigger network requests. Call `initialize()` from the feature that needs abilities — for example, when the workflow palette opens. Repeated calls return the same in-flight or resolved promise, so the requests fire at most once.
|
|
27
25
|
|
|
28
26
|
```js
|
|
29
|
-
import '@wordpress/core-abilities';
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Initialization is asynchronous because categories and abilities are fetched from the REST API. To wait for registration to finish before calling `getAbilities()` or `executeAbility()`, await the exported `ready` promise:
|
|
33
|
-
|
|
34
|
-
```js
|
|
35
|
-
import { ready } from '@wordpress/core-abilities';
|
|
27
|
+
import { initialize } from '@wordpress/core-abilities';
|
|
36
28
|
import { getAbilities, executeAbility } from '@wordpress/abilities';
|
|
37
29
|
|
|
38
|
-
await
|
|
30
|
+
await initialize();
|
|
39
31
|
|
|
40
32
|
console.log( getAbilities() );
|
|
41
33
|
console.log( await executeAbility( 'core/get-site-info' ) );
|
package/build/index.cjs
CHANGED
|
@@ -30,7 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// packages/core-abilities/src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
-
|
|
33
|
+
initialize: () => initialize
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(index_exports);
|
|
36
36
|
var import_abilities = require("@wordpress/abilities");
|
|
@@ -111,13 +111,18 @@ async function initializeAbilities() {
|
|
|
111
111
|
console.error("Failed to fetch abilities:", error);
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
var initializePromise = null;
|
|
115
|
+
function initialize() {
|
|
116
|
+
if (!initializePromise) {
|
|
117
|
+
initializePromise = (async () => {
|
|
118
|
+
await initializeCategories();
|
|
119
|
+
await initializeAbilities();
|
|
120
|
+
})();
|
|
121
|
+
}
|
|
122
|
+
return initializePromise;
|
|
117
123
|
}
|
|
118
|
-
var ready = initialize();
|
|
119
124
|
// Annotate the CommonJS export names for ESM import in node:
|
|
120
125
|
0 && (module.exports = {
|
|
121
|
-
|
|
126
|
+
initialize
|
|
122
127
|
});
|
|
123
128
|
//# sourceMappingURL=index.cjs.map
|
package/build/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { registerAbility, registerAbilityCategory } from '@wordpress/abilities';\nimport type {\n\tAbility,\n\tAbilityCategory,\n\tAbilityInput,\n\tAbilityOutput,\n} from '@wordpress/abilities';\nimport apiFetch from '@wordpress/api-fetch';\nimport { addQueryArgs } from '@wordpress/url';\n\n/**\n * API endpoint constants.\n */\nconst API_BASE = '/wp-abilities/v1';\nconst ABILITIES_ENDPOINT = `${ API_BASE }/abilities`;\nconst CATEGORIES_ENDPOINT = `${ API_BASE }/categories`;\n\n/**\n * Creates a serverCallback function for a WordPress REST API ability.\n *\n * @param ability The ability to create a callback for.\n * @return The serverCallback function.\n */\nfunction createServerCallback(\n\tability: Ability\n): ( input: AbilityInput ) => Promise< AbilityOutput > {\n\treturn async ( input: AbilityInput ) => {\n\t\t// Determine HTTP method based on ability annotations\n\t\tlet method = 'POST';\n\t\tif ( !! ability.meta?.annotations?.readonly ) {\n\t\t\tmethod = 'GET';\n\t\t} else if (\n\t\t\t!! ability.meta?.annotations?.destructive &&\n\t\t\t!! ability.meta?.annotations?.idempotent\n\t\t) {\n\t\t\tmethod = 'DELETE';\n\t\t}\n\n\t\tlet path = `${ ABILITIES_ENDPOINT }/${ ability.name }/run`;\n\t\tconst options: {\n\t\t\tmethod: string;\n\t\t\tdata?: { input: AbilityInput };\n\t\t} = {\n\t\t\tmethod,\n\t\t};\n\n\t\tif (\n\t\t\t[ 'GET', 'DELETE' ].includes( method ) &&\n\t\t\tinput !== null &&\n\t\t\tinput !== undefined\n\t\t) {\n\t\t\t// For GET and DELETE requests, pass the input as query parameters.\n\t\t\tpath = addQueryArgs( path, { input } );\n\t\t} else if (\n\t\t\tmethod === 'POST' &&\n\t\t\tinput !== null &&\n\t\t\tinput !== undefined\n\t\t) {\n\t\t\toptions.data = { input };\n\t\t}\n\n\t\t// Input and output validation happens on the server side for these abilities.\n\t\treturn apiFetch< AbilityOutput >( {\n\t\t\tpath,\n\t\t\t...options,\n\t\t} );\n\t};\n}\n\n/**\n * Fetches and registers all ability categories from WordPress.\n */\nasync function initializeCategories(): Promise< void > {\n\ttry {\n\t\tconst categories = await apiFetch< AbilityCategory[] >( {\n\t\t\tpath: addQueryArgs( CATEGORIES_ENDPOINT, {\n\t\t\t\tper_page: -1,\n\t\t\t\tcontext: 'edit',\n\t\t\t} ),\n\t\t} );\n\n\t\tif ( categories && Array.isArray( categories ) ) {\n\t\t\tfor ( const category of categories ) {\n\t\t\t\tregisterAbilityCategory( category.slug, {\n\t\t\t\t\tlabel: category.label,\n\t\t\t\t\tdescription: category.description,\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tannotations: { serverRegistered: true },\n\t\t\t\t\t},\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t} catch ( error ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error( 'Failed to fetch ability categories:', error );\n\t}\n}\n\n/**\n * Fetches and registers all abilities from WordPress.\n */\nasync function initializeAbilities(): Promise< void > {\n\ttry {\n\t\tconst abilities = await apiFetch< Ability[] >( {\n\t\t\tpath: addQueryArgs( ABILITIES_ENDPOINT, {\n\t\t\t\tper_page: -1,\n\t\t\t\tcontext: 'edit',\n\t\t\t} ),\n\t\t} );\n\n\t\tif ( abilities && Array.isArray( abilities ) ) {\n\t\t\tfor ( const ability of abilities ) {\n\t\t\t\t// Register the ability with a callback\n\t\t\t\t// The abilities package filters annotations to allowed keys\n\t\t\t\tregisterAbility( {\n\t\t\t\t\t...ability,\n\t\t\t\t\tcallback: createServerCallback( ability ),\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tannotations: {\n\t\t\t\t\t\t\t...ability.meta?.annotations,\n\t\t\t\t\t\t\tserverRegistered: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t} catch ( error ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error( 'Failed to fetch abilities:', error );\n\t}\n}\n\n/**\n *
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,uBAAyD;AAOzD,uBAAqB;AACrB,iBAA6B;AAK7B,IAAM,WAAW;AACjB,IAAM,qBAAqB,GAAI,QAAS;AACxC,IAAM,sBAAsB,GAAI,QAAS;AAQzC,SAAS,qBACR,SACsD;AACtD,SAAO,OAAQ,UAAyB;AAEvC,QAAI,SAAS;AACb,QAAK,CAAC,CAAE,QAAQ,MAAM,aAAa,UAAW;AAC7C,eAAS;AAAA,IACV,WACC,CAAC,CAAE,QAAQ,MAAM,aAAa,eAC9B,CAAC,CAAE,QAAQ,MAAM,aAAa,YAC7B;AACD,eAAS;AAAA,IACV;AAEA,QAAI,OAAO,GAAI,kBAAmB,IAAK,QAAQ,IAAK;AACpD,UAAM,UAGF;AAAA,MACH;AAAA,IACD;AAEA,QACC,CAAE,OAAO,QAAS,EAAE,SAAU,MAAO,KACrC,UAAU,QACV,UAAU,QACT;AAED,iBAAO,yBAAc,MAAM,EAAE,MAAM,CAAE;AAAA,IACtC,WACC,WAAW,UACX,UAAU,QACV,UAAU,QACT;AACD,cAAQ,OAAO,EAAE,MAAM;AAAA,IACxB;AAGA,eAAO,iBAAAA,SAA2B;AAAA,MACjC;AAAA,MACA,GAAG;AAAA,IACJ,CAAE;AAAA,EACH;AACD;AAKA,eAAe,uBAAwC;AACtD,MAAI;AACH,UAAM,aAAa,UAAM,iBAAAA,SAA+B;AAAA,MACvD,UAAM,yBAAc,qBAAqB;AAAA,QACxC,UAAU;AAAA,QACV,SAAS;AAAA,MACV,CAAE;AAAA,IACH,CAAE;AAEF,QAAK,cAAc,MAAM,QAAS,UAAW,GAAI;AAChD,iBAAY,YAAY,YAAa;AACpC,sDAAyB,SAAS,MAAM;AAAA,UACvC,OAAO,SAAS;AAAA,UAChB,aAAa,SAAS;AAAA,UACtB,MAAM;AAAA,YACL,aAAa,EAAE,kBAAkB,KAAK;AAAA,UACvC;AAAA,QACD,CAAE;AAAA,MACH;AAAA,IACD;AAAA,EACD,SAAU,OAAQ;AAEjB,YAAQ,MAAO,uCAAuC,KAAM;AAAA,EAC7D;AACD;AAKA,eAAe,sBAAuC;AACrD,MAAI;AACH,UAAM,YAAY,UAAM,iBAAAA,SAAuB;AAAA,MAC9C,UAAM,yBAAc,oBAAoB;AAAA,QACvC,UAAU;AAAA,QACV,SAAS;AAAA,MACV,CAAE;AAAA,IACH,CAAE;AAEF,QAAK,aAAa,MAAM,QAAS,SAAU,GAAI;AAC9C,iBAAY,WAAW,WAAY;AAGlC,8CAAiB;AAAA,UAChB,GAAG;AAAA,UACH,UAAU,qBAAsB,OAAQ;AAAA,UACxC,MAAM;AAAA,YACL,aAAa;AAAA,cACZ,GAAG,QAAQ,MAAM;AAAA,cACjB,kBAAkB;AAAA,YACnB;AAAA,UACD;AAAA,QACD,CAAE;AAAA,MACH;AAAA,IACD;AAAA,EACD,SAAU,OAAQ;AAEjB,YAAQ,MAAO,8BAA8B,KAAM;AAAA,EACpD;AACD;
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { registerAbility, registerAbilityCategory } from '@wordpress/abilities';\nimport type {\n\tAbility,\n\tAbilityCategory,\n\tAbilityInput,\n\tAbilityOutput,\n} from '@wordpress/abilities';\nimport apiFetch from '@wordpress/api-fetch';\nimport { addQueryArgs } from '@wordpress/url';\n\n/**\n * API endpoint constants.\n */\nconst API_BASE = '/wp-abilities/v1';\nconst ABILITIES_ENDPOINT = `${ API_BASE }/abilities`;\nconst CATEGORIES_ENDPOINT = `${ API_BASE }/categories`;\n\n/**\n * Creates a serverCallback function for a WordPress REST API ability.\n *\n * @param ability The ability to create a callback for.\n * @return The serverCallback function.\n */\nfunction createServerCallback(\n\tability: Ability\n): ( input: AbilityInput ) => Promise< AbilityOutput > {\n\treturn async ( input: AbilityInput ) => {\n\t\t// Determine HTTP method based on ability annotations\n\t\tlet method = 'POST';\n\t\tif ( !! ability.meta?.annotations?.readonly ) {\n\t\t\tmethod = 'GET';\n\t\t} else if (\n\t\t\t!! ability.meta?.annotations?.destructive &&\n\t\t\t!! ability.meta?.annotations?.idempotent\n\t\t) {\n\t\t\tmethod = 'DELETE';\n\t\t}\n\n\t\tlet path = `${ ABILITIES_ENDPOINT }/${ ability.name }/run`;\n\t\tconst options: {\n\t\t\tmethod: string;\n\t\t\tdata?: { input: AbilityInput };\n\t\t} = {\n\t\t\tmethod,\n\t\t};\n\n\t\tif (\n\t\t\t[ 'GET', 'DELETE' ].includes( method ) &&\n\t\t\tinput !== null &&\n\t\t\tinput !== undefined\n\t\t) {\n\t\t\t// For GET and DELETE requests, pass the input as query parameters.\n\t\t\tpath = addQueryArgs( path, { input } );\n\t\t} else if (\n\t\t\tmethod === 'POST' &&\n\t\t\tinput !== null &&\n\t\t\tinput !== undefined\n\t\t) {\n\t\t\toptions.data = { input };\n\t\t}\n\n\t\t// Input and output validation happens on the server side for these abilities.\n\t\treturn apiFetch< AbilityOutput >( {\n\t\t\tpath,\n\t\t\t...options,\n\t\t} );\n\t};\n}\n\n/**\n * Fetches and registers all ability categories from WordPress.\n */\nasync function initializeCategories(): Promise< void > {\n\ttry {\n\t\tconst categories = await apiFetch< AbilityCategory[] >( {\n\t\t\tpath: addQueryArgs( CATEGORIES_ENDPOINT, {\n\t\t\t\tper_page: -1,\n\t\t\t\tcontext: 'edit',\n\t\t\t} ),\n\t\t} );\n\n\t\tif ( categories && Array.isArray( categories ) ) {\n\t\t\tfor ( const category of categories ) {\n\t\t\t\tregisterAbilityCategory( category.slug, {\n\t\t\t\t\tlabel: category.label,\n\t\t\t\t\tdescription: category.description,\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tannotations: { serverRegistered: true },\n\t\t\t\t\t},\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t} catch ( error ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error( 'Failed to fetch ability categories:', error );\n\t}\n}\n\n/**\n * Fetches and registers all abilities from WordPress.\n */\nasync function initializeAbilities(): Promise< void > {\n\ttry {\n\t\tconst abilities = await apiFetch< Ability[] >( {\n\t\t\tpath: addQueryArgs( ABILITIES_ENDPOINT, {\n\t\t\t\tper_page: -1,\n\t\t\t\tcontext: 'edit',\n\t\t\t} ),\n\t\t} );\n\n\t\tif ( abilities && Array.isArray( abilities ) ) {\n\t\t\tfor ( const ability of abilities ) {\n\t\t\t\t// Register the ability with a callback\n\t\t\t\t// The abilities package filters annotations to allowed keys\n\t\t\t\tregisterAbility( {\n\t\t\t\t\t...ability,\n\t\t\t\t\tcallback: createServerCallback( ability ),\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tannotations: {\n\t\t\t\t\t\t\t...ability.meta?.annotations,\n\t\t\t\t\t\t\tserverRegistered: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t} catch ( error ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error( 'Failed to fetch abilities:', error );\n\t}\n}\n\nlet initializePromise: Promise< void > | null = null;\n\n/**\n * Fetches and registers core abilities and their categories.\n *\n * Memoized: repeated calls return the same in-flight or resolved promise, so\n * callers can invoke it from multiple entry points without triggering duplicate\n * REST requests.\n */\nexport function initialize(): Promise< void > {\n\tif ( ! initializePromise ) {\n\t\tinitializePromise = ( async () => {\n\t\t\tawait initializeCategories();\n\t\t\tawait initializeAbilities();\n\t\t} )();\n\t}\n\treturn initializePromise;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,uBAAyD;AAOzD,uBAAqB;AACrB,iBAA6B;AAK7B,IAAM,WAAW;AACjB,IAAM,qBAAqB,GAAI,QAAS;AACxC,IAAM,sBAAsB,GAAI,QAAS;AAQzC,SAAS,qBACR,SACsD;AACtD,SAAO,OAAQ,UAAyB;AAEvC,QAAI,SAAS;AACb,QAAK,CAAC,CAAE,QAAQ,MAAM,aAAa,UAAW;AAC7C,eAAS;AAAA,IACV,WACC,CAAC,CAAE,QAAQ,MAAM,aAAa,eAC9B,CAAC,CAAE,QAAQ,MAAM,aAAa,YAC7B;AACD,eAAS;AAAA,IACV;AAEA,QAAI,OAAO,GAAI,kBAAmB,IAAK,QAAQ,IAAK;AACpD,UAAM,UAGF;AAAA,MACH;AAAA,IACD;AAEA,QACC,CAAE,OAAO,QAAS,EAAE,SAAU,MAAO,KACrC,UAAU,QACV,UAAU,QACT;AAED,iBAAO,yBAAc,MAAM,EAAE,MAAM,CAAE;AAAA,IACtC,WACC,WAAW,UACX,UAAU,QACV,UAAU,QACT;AACD,cAAQ,OAAO,EAAE,MAAM;AAAA,IACxB;AAGA,eAAO,iBAAAA,SAA2B;AAAA,MACjC;AAAA,MACA,GAAG;AAAA,IACJ,CAAE;AAAA,EACH;AACD;AAKA,eAAe,uBAAwC;AACtD,MAAI;AACH,UAAM,aAAa,UAAM,iBAAAA,SAA+B;AAAA,MACvD,UAAM,yBAAc,qBAAqB;AAAA,QACxC,UAAU;AAAA,QACV,SAAS;AAAA,MACV,CAAE;AAAA,IACH,CAAE;AAEF,QAAK,cAAc,MAAM,QAAS,UAAW,GAAI;AAChD,iBAAY,YAAY,YAAa;AACpC,sDAAyB,SAAS,MAAM;AAAA,UACvC,OAAO,SAAS;AAAA,UAChB,aAAa,SAAS;AAAA,UACtB,MAAM;AAAA,YACL,aAAa,EAAE,kBAAkB,KAAK;AAAA,UACvC;AAAA,QACD,CAAE;AAAA,MACH;AAAA,IACD;AAAA,EACD,SAAU,OAAQ;AAEjB,YAAQ,MAAO,uCAAuC,KAAM;AAAA,EAC7D;AACD;AAKA,eAAe,sBAAuC;AACrD,MAAI;AACH,UAAM,YAAY,UAAM,iBAAAA,SAAuB;AAAA,MAC9C,UAAM,yBAAc,oBAAoB;AAAA,QACvC,UAAU;AAAA,QACV,SAAS;AAAA,MACV,CAAE;AAAA,IACH,CAAE;AAEF,QAAK,aAAa,MAAM,QAAS,SAAU,GAAI;AAC9C,iBAAY,WAAW,WAAY;AAGlC,8CAAiB;AAAA,UAChB,GAAG;AAAA,UACH,UAAU,qBAAsB,OAAQ;AAAA,UACxC,MAAM;AAAA,YACL,aAAa;AAAA,cACZ,GAAG,QAAQ,MAAM;AAAA,cACjB,kBAAkB;AAAA,YACnB;AAAA,UACD;AAAA,QACD,CAAE;AAAA,MACH;AAAA,IACD;AAAA,EACD,SAAU,OAAQ;AAEjB,YAAQ,MAAO,8BAA8B,KAAM;AAAA,EACpD;AACD;AAEA,IAAI,oBAA4C;AASzC,SAAS,aAA8B;AAC7C,MAAK,CAAE,mBAAoB;AAC1B,yBAAsB,YAAY;AACjC,YAAM,qBAAqB;AAC3B,YAAM,oBAAoB;AAAA,IAC3B,GAAI;AAAA,EACL;AACA,SAAO;AACR;",
|
|
6
6
|
"names": ["apiFetch"]
|
|
7
7
|
}
|
package/build-module/index.mjs
CHANGED
|
@@ -77,12 +77,17 @@ async function initializeAbilities() {
|
|
|
77
77
|
console.error("Failed to fetch abilities:", error);
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
var initializePromise = null;
|
|
81
|
+
function initialize() {
|
|
82
|
+
if (!initializePromise) {
|
|
83
|
+
initializePromise = (async () => {
|
|
84
|
+
await initializeCategories();
|
|
85
|
+
await initializeAbilities();
|
|
86
|
+
})();
|
|
87
|
+
}
|
|
88
|
+
return initializePromise;
|
|
83
89
|
}
|
|
84
|
-
var ready = initialize();
|
|
85
90
|
export {
|
|
86
|
-
|
|
91
|
+
initialize
|
|
87
92
|
};
|
|
88
93
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { registerAbility, registerAbilityCategory } from '@wordpress/abilities';\nimport type {\n\tAbility,\n\tAbilityCategory,\n\tAbilityInput,\n\tAbilityOutput,\n} from '@wordpress/abilities';\nimport apiFetch from '@wordpress/api-fetch';\nimport { addQueryArgs } from '@wordpress/url';\n\n/**\n * API endpoint constants.\n */\nconst API_BASE = '/wp-abilities/v1';\nconst ABILITIES_ENDPOINT = `${ API_BASE }/abilities`;\nconst CATEGORIES_ENDPOINT = `${ API_BASE }/categories`;\n\n/**\n * Creates a serverCallback function for a WordPress REST API ability.\n *\n * @param ability The ability to create a callback for.\n * @return The serverCallback function.\n */\nfunction createServerCallback(\n\tability: Ability\n): ( input: AbilityInput ) => Promise< AbilityOutput > {\n\treturn async ( input: AbilityInput ) => {\n\t\t// Determine HTTP method based on ability annotations\n\t\tlet method = 'POST';\n\t\tif ( !! ability.meta?.annotations?.readonly ) {\n\t\t\tmethod = 'GET';\n\t\t} else if (\n\t\t\t!! ability.meta?.annotations?.destructive &&\n\t\t\t!! ability.meta?.annotations?.idempotent\n\t\t) {\n\t\t\tmethod = 'DELETE';\n\t\t}\n\n\t\tlet path = `${ ABILITIES_ENDPOINT }/${ ability.name }/run`;\n\t\tconst options: {\n\t\t\tmethod: string;\n\t\t\tdata?: { input: AbilityInput };\n\t\t} = {\n\t\t\tmethod,\n\t\t};\n\n\t\tif (\n\t\t\t[ 'GET', 'DELETE' ].includes( method ) &&\n\t\t\tinput !== null &&\n\t\t\tinput !== undefined\n\t\t) {\n\t\t\t// For GET and DELETE requests, pass the input as query parameters.\n\t\t\tpath = addQueryArgs( path, { input } );\n\t\t} else if (\n\t\t\tmethod === 'POST' &&\n\t\t\tinput !== null &&\n\t\t\tinput !== undefined\n\t\t) {\n\t\t\toptions.data = { input };\n\t\t}\n\n\t\t// Input and output validation happens on the server side for these abilities.\n\t\treturn apiFetch< AbilityOutput >( {\n\t\t\tpath,\n\t\t\t...options,\n\t\t} );\n\t};\n}\n\n/**\n * Fetches and registers all ability categories from WordPress.\n */\nasync function initializeCategories(): Promise< void > {\n\ttry {\n\t\tconst categories = await apiFetch< AbilityCategory[] >( {\n\t\t\tpath: addQueryArgs( CATEGORIES_ENDPOINT, {\n\t\t\t\tper_page: -1,\n\t\t\t\tcontext: 'edit',\n\t\t\t} ),\n\t\t} );\n\n\t\tif ( categories && Array.isArray( categories ) ) {\n\t\t\tfor ( const category of categories ) {\n\t\t\t\tregisterAbilityCategory( category.slug, {\n\t\t\t\t\tlabel: category.label,\n\t\t\t\t\tdescription: category.description,\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tannotations: { serverRegistered: true },\n\t\t\t\t\t},\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t} catch ( error ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error( 'Failed to fetch ability categories:', error );\n\t}\n}\n\n/**\n * Fetches and registers all abilities from WordPress.\n */\nasync function initializeAbilities(): Promise< void > {\n\ttry {\n\t\tconst abilities = await apiFetch< Ability[] >( {\n\t\t\tpath: addQueryArgs( ABILITIES_ENDPOINT, {\n\t\t\t\tper_page: -1,\n\t\t\t\tcontext: 'edit',\n\t\t\t} ),\n\t\t} );\n\n\t\tif ( abilities && Array.isArray( abilities ) ) {\n\t\t\tfor ( const ability of abilities ) {\n\t\t\t\t// Register the ability with a callback\n\t\t\t\t// The abilities package filters annotations to allowed keys\n\t\t\t\tregisterAbility( {\n\t\t\t\t\t...ability,\n\t\t\t\t\tcallback: createServerCallback( ability ),\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tannotations: {\n\t\t\t\t\t\t\t...ability.meta?.annotations,\n\t\t\t\t\t\t\tserverRegistered: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t} catch ( error ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error( 'Failed to fetch abilities:', error );\n\t}\n}\n\n/**\n *
|
|
5
|
-
"mappings": ";AAGA,SAAS,iBAAiB,+BAA+B;AAOzD,OAAO,cAAc;AACrB,SAAS,oBAAoB;AAK7B,IAAM,WAAW;AACjB,IAAM,qBAAqB,GAAI,QAAS;AACxC,IAAM,sBAAsB,GAAI,QAAS;AAQzC,SAAS,qBACR,SACsD;AACtD,SAAO,OAAQ,UAAyB;AAEvC,QAAI,SAAS;AACb,QAAK,CAAC,CAAE,QAAQ,MAAM,aAAa,UAAW;AAC7C,eAAS;AAAA,IACV,WACC,CAAC,CAAE,QAAQ,MAAM,aAAa,eAC9B,CAAC,CAAE,QAAQ,MAAM,aAAa,YAC7B;AACD,eAAS;AAAA,IACV;AAEA,QAAI,OAAO,GAAI,kBAAmB,IAAK,QAAQ,IAAK;AACpD,UAAM,UAGF;AAAA,MACH;AAAA,IACD;AAEA,QACC,CAAE,OAAO,QAAS,EAAE,SAAU,MAAO,KACrC,UAAU,QACV,UAAU,QACT;AAED,aAAO,aAAc,MAAM,EAAE,MAAM,CAAE;AAAA,IACtC,WACC,WAAW,UACX,UAAU,QACV,UAAU,QACT;AACD,cAAQ,OAAO,EAAE,MAAM;AAAA,IACxB;AAGA,WAAO,SAA2B;AAAA,MACjC;AAAA,MACA,GAAG;AAAA,IACJ,CAAE;AAAA,EACH;AACD;AAKA,eAAe,uBAAwC;AACtD,MAAI;AACH,UAAM,aAAa,MAAM,SAA+B;AAAA,MACvD,MAAM,aAAc,qBAAqB;AAAA,QACxC,UAAU;AAAA,QACV,SAAS;AAAA,MACV,CAAE;AAAA,IACH,CAAE;AAEF,QAAK,cAAc,MAAM,QAAS,UAAW,GAAI;AAChD,iBAAY,YAAY,YAAa;AACpC,gCAAyB,SAAS,MAAM;AAAA,UACvC,OAAO,SAAS;AAAA,UAChB,aAAa,SAAS;AAAA,UACtB,MAAM;AAAA,YACL,aAAa,EAAE,kBAAkB,KAAK;AAAA,UACvC;AAAA,QACD,CAAE;AAAA,MACH;AAAA,IACD;AAAA,EACD,SAAU,OAAQ;AAEjB,YAAQ,MAAO,uCAAuC,KAAM;AAAA,EAC7D;AACD;AAKA,eAAe,sBAAuC;AACrD,MAAI;AACH,UAAM,YAAY,MAAM,SAAuB;AAAA,MAC9C,MAAM,aAAc,oBAAoB;AAAA,QACvC,UAAU;AAAA,QACV,SAAS;AAAA,MACV,CAAE;AAAA,IACH,CAAE;AAEF,QAAK,aAAa,MAAM,QAAS,SAAU,GAAI;AAC9C,iBAAY,WAAW,WAAY;AAGlC,wBAAiB;AAAA,UAChB,GAAG;AAAA,UACH,UAAU,qBAAsB,OAAQ;AAAA,UACxC,MAAM;AAAA,YACL,aAAa;AAAA,cACZ,GAAG,QAAQ,MAAM;AAAA,cACjB,kBAAkB;AAAA,YACnB;AAAA,UACD;AAAA,QACD,CAAE;AAAA,MACH;AAAA,IACD;AAAA,EACD,SAAU,OAAQ;AAEjB,YAAQ,MAAO,8BAA8B,KAAM;AAAA,EACpD;AACD;
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { registerAbility, registerAbilityCategory } from '@wordpress/abilities';\nimport type {\n\tAbility,\n\tAbilityCategory,\n\tAbilityInput,\n\tAbilityOutput,\n} from '@wordpress/abilities';\nimport apiFetch from '@wordpress/api-fetch';\nimport { addQueryArgs } from '@wordpress/url';\n\n/**\n * API endpoint constants.\n */\nconst API_BASE = '/wp-abilities/v1';\nconst ABILITIES_ENDPOINT = `${ API_BASE }/abilities`;\nconst CATEGORIES_ENDPOINT = `${ API_BASE }/categories`;\n\n/**\n * Creates a serverCallback function for a WordPress REST API ability.\n *\n * @param ability The ability to create a callback for.\n * @return The serverCallback function.\n */\nfunction createServerCallback(\n\tability: Ability\n): ( input: AbilityInput ) => Promise< AbilityOutput > {\n\treturn async ( input: AbilityInput ) => {\n\t\t// Determine HTTP method based on ability annotations\n\t\tlet method = 'POST';\n\t\tif ( !! ability.meta?.annotations?.readonly ) {\n\t\t\tmethod = 'GET';\n\t\t} else if (\n\t\t\t!! ability.meta?.annotations?.destructive &&\n\t\t\t!! ability.meta?.annotations?.idempotent\n\t\t) {\n\t\t\tmethod = 'DELETE';\n\t\t}\n\n\t\tlet path = `${ ABILITIES_ENDPOINT }/${ ability.name }/run`;\n\t\tconst options: {\n\t\t\tmethod: string;\n\t\t\tdata?: { input: AbilityInput };\n\t\t} = {\n\t\t\tmethod,\n\t\t};\n\n\t\tif (\n\t\t\t[ 'GET', 'DELETE' ].includes( method ) &&\n\t\t\tinput !== null &&\n\t\t\tinput !== undefined\n\t\t) {\n\t\t\t// For GET and DELETE requests, pass the input as query parameters.\n\t\t\tpath = addQueryArgs( path, { input } );\n\t\t} else if (\n\t\t\tmethod === 'POST' &&\n\t\t\tinput !== null &&\n\t\t\tinput !== undefined\n\t\t) {\n\t\t\toptions.data = { input };\n\t\t}\n\n\t\t// Input and output validation happens on the server side for these abilities.\n\t\treturn apiFetch< AbilityOutput >( {\n\t\t\tpath,\n\t\t\t...options,\n\t\t} );\n\t};\n}\n\n/**\n * Fetches and registers all ability categories from WordPress.\n */\nasync function initializeCategories(): Promise< void > {\n\ttry {\n\t\tconst categories = await apiFetch< AbilityCategory[] >( {\n\t\t\tpath: addQueryArgs( CATEGORIES_ENDPOINT, {\n\t\t\t\tper_page: -1,\n\t\t\t\tcontext: 'edit',\n\t\t\t} ),\n\t\t} );\n\n\t\tif ( categories && Array.isArray( categories ) ) {\n\t\t\tfor ( const category of categories ) {\n\t\t\t\tregisterAbilityCategory( category.slug, {\n\t\t\t\t\tlabel: category.label,\n\t\t\t\t\tdescription: category.description,\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tannotations: { serverRegistered: true },\n\t\t\t\t\t},\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t} catch ( error ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error( 'Failed to fetch ability categories:', error );\n\t}\n}\n\n/**\n * Fetches and registers all abilities from WordPress.\n */\nasync function initializeAbilities(): Promise< void > {\n\ttry {\n\t\tconst abilities = await apiFetch< Ability[] >( {\n\t\t\tpath: addQueryArgs( ABILITIES_ENDPOINT, {\n\t\t\t\tper_page: -1,\n\t\t\t\tcontext: 'edit',\n\t\t\t} ),\n\t\t} );\n\n\t\tif ( abilities && Array.isArray( abilities ) ) {\n\t\t\tfor ( const ability of abilities ) {\n\t\t\t\t// Register the ability with a callback\n\t\t\t\t// The abilities package filters annotations to allowed keys\n\t\t\t\tregisterAbility( {\n\t\t\t\t\t...ability,\n\t\t\t\t\tcallback: createServerCallback( ability ),\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tannotations: {\n\t\t\t\t\t\t\t...ability.meta?.annotations,\n\t\t\t\t\t\t\tserverRegistered: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t} catch ( error ) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error( 'Failed to fetch abilities:', error );\n\t}\n}\n\nlet initializePromise: Promise< void > | null = null;\n\n/**\n * Fetches and registers core abilities and their categories.\n *\n * Memoized: repeated calls return the same in-flight or resolved promise, so\n * callers can invoke it from multiple entry points without triggering duplicate\n * REST requests.\n */\nexport function initialize(): Promise< void > {\n\tif ( ! initializePromise ) {\n\t\tinitializePromise = ( async () => {\n\t\t\tawait initializeCategories();\n\t\t\tawait initializeAbilities();\n\t\t} )();\n\t}\n\treturn initializePromise;\n}\n"],
|
|
5
|
+
"mappings": ";AAGA,SAAS,iBAAiB,+BAA+B;AAOzD,OAAO,cAAc;AACrB,SAAS,oBAAoB;AAK7B,IAAM,WAAW;AACjB,IAAM,qBAAqB,GAAI,QAAS;AACxC,IAAM,sBAAsB,GAAI,QAAS;AAQzC,SAAS,qBACR,SACsD;AACtD,SAAO,OAAQ,UAAyB;AAEvC,QAAI,SAAS;AACb,QAAK,CAAC,CAAE,QAAQ,MAAM,aAAa,UAAW;AAC7C,eAAS;AAAA,IACV,WACC,CAAC,CAAE,QAAQ,MAAM,aAAa,eAC9B,CAAC,CAAE,QAAQ,MAAM,aAAa,YAC7B;AACD,eAAS;AAAA,IACV;AAEA,QAAI,OAAO,GAAI,kBAAmB,IAAK,QAAQ,IAAK;AACpD,UAAM,UAGF;AAAA,MACH;AAAA,IACD;AAEA,QACC,CAAE,OAAO,QAAS,EAAE,SAAU,MAAO,KACrC,UAAU,QACV,UAAU,QACT;AAED,aAAO,aAAc,MAAM,EAAE,MAAM,CAAE;AAAA,IACtC,WACC,WAAW,UACX,UAAU,QACV,UAAU,QACT;AACD,cAAQ,OAAO,EAAE,MAAM;AAAA,IACxB;AAGA,WAAO,SAA2B;AAAA,MACjC;AAAA,MACA,GAAG;AAAA,IACJ,CAAE;AAAA,EACH;AACD;AAKA,eAAe,uBAAwC;AACtD,MAAI;AACH,UAAM,aAAa,MAAM,SAA+B;AAAA,MACvD,MAAM,aAAc,qBAAqB;AAAA,QACxC,UAAU;AAAA,QACV,SAAS;AAAA,MACV,CAAE;AAAA,IACH,CAAE;AAEF,QAAK,cAAc,MAAM,QAAS,UAAW,GAAI;AAChD,iBAAY,YAAY,YAAa;AACpC,gCAAyB,SAAS,MAAM;AAAA,UACvC,OAAO,SAAS;AAAA,UAChB,aAAa,SAAS;AAAA,UACtB,MAAM;AAAA,YACL,aAAa,EAAE,kBAAkB,KAAK;AAAA,UACvC;AAAA,QACD,CAAE;AAAA,MACH;AAAA,IACD;AAAA,EACD,SAAU,OAAQ;AAEjB,YAAQ,MAAO,uCAAuC,KAAM;AAAA,EAC7D;AACD;AAKA,eAAe,sBAAuC;AACrD,MAAI;AACH,UAAM,YAAY,MAAM,SAAuB;AAAA,MAC9C,MAAM,aAAc,oBAAoB;AAAA,QACvC,UAAU;AAAA,QACV,SAAS;AAAA,MACV,CAAE;AAAA,IACH,CAAE;AAEF,QAAK,aAAa,MAAM,QAAS,SAAU,GAAI;AAC9C,iBAAY,WAAW,WAAY;AAGlC,wBAAiB;AAAA,UAChB,GAAG;AAAA,UACH,UAAU,qBAAsB,OAAQ;AAAA,UACxC,MAAM;AAAA,YACL,aAAa;AAAA,cACZ,GAAG,QAAQ,MAAM;AAAA,cACjB,kBAAkB;AAAA,YACnB;AAAA,UACD;AAAA,QACD,CAAE;AAAA,MACH;AAAA,IACD;AAAA,EACD,SAAU,OAAQ;AAEjB,YAAQ,MAAO,8BAA8B,KAAM;AAAA,EACpD;AACD;AAEA,IAAI,oBAA4C;AASzC,SAAS,aAA8B;AAC7C,MAAK,CAAE,mBAAoB;AAC1B,yBAAsB,YAAY;AACjC,YAAM,qBAAqB;AAC3B,YAAM,oBAAoB;AAAA,IAC3B,GAAI;AAAA,EACL;AACA,SAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/build-types/index.d.ts
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Fetches and registers core abilities and their categories.
|
|
3
|
+
*
|
|
4
|
+
* Memoized: repeated calls return the same in-flight or resolved promise, so
|
|
5
|
+
* callers can invoke it from multiple entry points without triggering duplicate
|
|
6
|
+
* REST requests.
|
|
7
|
+
*/
|
|
8
|
+
export declare function initialize(): Promise<void>;
|
|
2
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAyIA;;;;;;GAMG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAAE,IAAI,CAAE,CAQ5C"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/core-abilities",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "WordPress core abilities integration for the Abilities API.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
"types": "build-types",
|
|
47
47
|
"sideEffects": true,
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@wordpress/abilities": "^0.
|
|
50
|
-
"@wordpress/api-fetch": "^7.
|
|
51
|
-
"@wordpress/url": "^4.
|
|
49
|
+
"@wordpress/abilities": "^0.14.0",
|
|
50
|
+
"@wordpress/api-fetch": "^7.48.0",
|
|
51
|
+
"@wordpress/url": "^4.48.0"
|
|
52
52
|
},
|
|
53
53
|
"publishConfig": {
|
|
54
54
|
"access": "public"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "ace624620394585491b7f0c28ff0d3a8c13d50d8"
|
|
57
57
|
}
|
package/src/index.ts
CHANGED
|
@@ -133,14 +133,21 @@ async function initializeAbilities(): Promise< void > {
|
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
+
let initializePromise: Promise< void > | null = null;
|
|
137
|
+
|
|
136
138
|
/**
|
|
137
|
-
*
|
|
139
|
+
* Fetches and registers core abilities and their categories.
|
|
140
|
+
*
|
|
141
|
+
* Memoized: repeated calls return the same in-flight or resolved promise, so
|
|
142
|
+
* callers can invoke it from multiple entry points without triggering duplicate
|
|
143
|
+
* REST requests.
|
|
138
144
|
*/
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
145
|
+
export function initialize(): Promise< void > {
|
|
146
|
+
if ( ! initializePromise ) {
|
|
147
|
+
initializePromise = ( async () => {
|
|
148
|
+
await initializeCategories();
|
|
149
|
+
await initializeAbilities();
|
|
150
|
+
} )();
|
|
151
|
+
}
|
|
152
|
+
return initializePromise;
|
|
143
153
|
}
|
|
144
|
-
|
|
145
|
-
// Auto-initialize on import.
|
|
146
|
-
export const ready: Promise< void > = initialize();
|