PluginProbe
Gutenberg / 16.2.0
Gutenberg v16.2.0
24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 All 403 releases
gutenberg / build / core-data / index.js

index.js in Gutenberg 16.2.0, at build/core-data/index.js

7,398 lines 214.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (() => { // webpackBootstrap
2 /******/ "use strict";
3 /******/ var __webpack_modules__ = ({
4
5 /***/ 2167:
6 /***/ ((module) => {
7
8
9
10 function _typeof(obj) {
11 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
12 _typeof = function (obj) {
13 return typeof obj;
14 };
15 } else {
16 _typeof = function (obj) {
17 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
18 };
19 }
20
21 return _typeof(obj);
22 }
23
24 function _classCallCheck(instance, Constructor) {
25 if (!(instance instanceof Constructor)) {
26 throw new TypeError("Cannot call a class as a function");
27 }
28 }
29
30 function _defineProperties(target, props) {
31 for (var i = 0; i < props.length; i++) {
32 var descriptor = props[i];
33 descriptor.enumerable = descriptor.enumerable || false;
34 descriptor.configurable = true;
35 if ("value" in descriptor) descriptor.writable = true;
36 Object.defineProperty(target, descriptor.key, descriptor);
37 }
38 }
39
40 function _createClass(Constructor, protoProps, staticProps) {
41 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
42 if (staticProps) _defineProperties(Constructor, staticProps);
43 return Constructor;
44 }
45
46 /**
47 * Given an instance of EquivalentKeyMap, returns its internal value pair tuple
48 * for a key, if one exists. The tuple members consist of the last reference
49 * value for the key (used in efficient subsequent lookups) and the value
50 * assigned for the key at the leaf node.
51 *
52 * @param {EquivalentKeyMap} instance EquivalentKeyMap instance.
53 * @param {*} key The key for which to return value pair.
54 *
55 * @return {?Array} Value pair, if exists.
56 */
57 function getValuePair(instance, key) {
58 var _map = instance._map,
59 _arrayTreeMap = instance._arrayTreeMap,
60 _objectTreeMap = instance._objectTreeMap; // Map keeps a reference to the last object-like key used to set the
61 // value, which can be used to shortcut immediately to the value.
62
63 if (_map.has(key)) {
64 return _map.get(key);
65 } // Sort keys to ensure stable retrieval from tree.
66
67
68 var properties = Object.keys(key).sort(); // Tree by type to avoid conflicts on numeric object keys, empty value.
69
70 var map = Array.isArray(key) ? _arrayTreeMap : _objectTreeMap;
71
72 for (var i = 0; i < properties.length; i++) {
73 var property = properties[i];
74 map = map.get(property);
75
76 if (map === undefined) {
77 return;
78 }
79
80 var propertyValue = key[property];
81 map = map.get(propertyValue);
82
83 if (map === undefined) {
84 return;
85 }
86 }
87
88 var valuePair = map.get('_ekm_value');
89
90 if (!valuePair) {
91 return;
92 } // If reached, it implies that an object-like key was set with another
93 // reference, so delete the reference and replace with the current.
94
95
96 _map.delete(valuePair[0]);
97
98 valuePair[0] = key;
99 map.set('_ekm_value', valuePair);
100
101 _map.set(key, valuePair);
102
103 return valuePair;
104 }
105 /**
106 * Variant of a Map object which enables lookup by equivalent (deeply equal)
107 * object and array keys.
108 */
109
110
111 var EquivalentKeyMap =
112 /*#__PURE__*/
113 function () {
114 /**
115 * Constructs a new instance of EquivalentKeyMap.
116 *
117 * @param {Iterable.<*>} iterable Initial pair of key, value for map.
118 */
119 function EquivalentKeyMap(iterable) {
120 _classCallCheck(this, EquivalentKeyMap);
121
122 this.clear();
123
124 if (iterable instanceof EquivalentKeyMap) {
125 // Map#forEach is only means of iterating with support for IE11.
126 var iterablePairs = [];
127 iterable.forEach(function (value, key) {
128 iterablePairs.push([key, value]);
129 });
130 iterable = iterablePairs;
131 }
132
133 if (iterable != null) {
134 for (var i = 0; i < iterable.length; i++) {
135 this.set(iterable[i][0], iterable[i][1]);
136 }
137 }
138 }
139 /**
140 * Accessor property returning the number of elements.
141 *
142 * @return {number} Number of elements.
143 */
144
145
146 _createClass(EquivalentKeyMap, [{
147 key: "set",
148
149 /**
150 * Add or update an element with a specified key and value.
151 *
152 * @param {*} key The key of the element to add.
153 * @param {*} value The value of the element to add.
154 *
155 * @return {EquivalentKeyMap} Map instance.
156 */
157 value: function set(key, value) {
158 // Shortcut non-object-like to set on internal Map.
159 if (key === null || _typeof(key) !== 'object') {
160 this._map.set(key, value);
161
162 return this;
163 } // Sort keys to ensure stable assignment into tree.
164
165
166 var properties = Object.keys(key).sort();
167 var valuePair = [key, value]; // Tree by type to avoid conflicts on numeric object keys, empty value.
168
169 var map = Array.isArray(key) ? this._arrayTreeMap : this._objectTreeMap;
170
171 for (var i = 0; i < properties.length; i++) {
172 var property = properties[i];
173
174 if (!map.has(property)) {
175 map.set(property, new EquivalentKeyMap());
176 }
177
178 map = map.get(property);
179 var propertyValue = key[property];
180
181 if (!map.has(propertyValue)) {
182 map.set(propertyValue, new EquivalentKeyMap());
183 }
184
185 map = map.get(propertyValue);
186 } // If an _ekm_value exists, there was already an equivalent key. Before
187 // overriding, ensure that the old key reference is removed from map to
188 // avoid memory leak of accumulating equivalent keys. This is, in a
189 // sense, a poor man's WeakMap, while still enabling iterability.
190
191
192 var previousValuePair = map.get('_ekm_value');
193
194 if (previousValuePair) {
195 this._map.delete(previousValuePair[0]);
196 }
197
198 map.set('_ekm_value', valuePair);
199
200 this._map.set(key, valuePair);
201
202 return this;
203 }
204 /**
205 * Returns a specified element.
206 *
207 * @param {*} key The key of the element to return.
208 *
209 * @return {?*} The element associated with the specified key or undefined
210 * if the key can't be found.
211 */
212
213 }, {
214 key: "get",
215 value: function get(key) {
216 // Shortcut non-object-like to get from internal Map.
217 if (key === null || _typeof(key) !== 'object') {
218 return this._map.get(key);
219 }
220
221 var valuePair = getValuePair(this, key);
222
223 if (valuePair) {
224 return valuePair[1];
225 }
226 }
227 /**
228 * Returns a boolean indicating whether an element with the specified key
229 * exists or not.
230 *
231 * @param {*} key The key of the element to test for presence.
232 *
233 * @return {boolean} Whether an element with the specified key exists.
234 */
235
236 }, {
237 key: "has",
238 value: function has(key) {
239 if (key === null || _typeof(key) !== 'object') {
240 return this._map.has(key);
241 } // Test on the _presence_ of the pair, not its value, as even undefined
242 // can be a valid member value for a key.
243
244
245 return getValuePair(this, key) !== undefined;
246 }
247 /**
248 * Removes the specified element.
249 *
250 * @param {*} key The key of the element to remove.
251 *
252 * @return {boolean} Returns true if an element existed and has been
253 * removed, or false if the element does not exist.
254 */
255
256 }, {
257 key: "delete",
258 value: function _delete(key) {
259 if (!this.has(key)) {
260 return false;
261 } // This naive implementation will leave orphaned child trees. A better
262 // implementation should traverse and remove orphans.
263
264
265 this.set(key, undefined);
266 return true;
267 }
268 /**
269 * Executes a provided function once per each key/value pair, in insertion
270 * order.
271 *
272 * @param {Function} callback Function to execute for each element.
273 * @param {*} thisArg Value to use as `this` when executing
274 * `callback`.
275 */
276
277 }, {
278 key: "forEach",
279 value: function forEach(callback) {
280 var _this = this;
281
282 var thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this;
283
284 this._map.forEach(function (value, key) {
285 // Unwrap value from object-like value pair.
286 if (key !== null && _typeof(key) === 'object') {
287 value = value[1];
288 }
289
290 callback.call(thisArg, value, key, _this);
291 });
292 }
293 /**
294 * Removes all elements.
295 */
296
297 }, {
298 key: "clear",
299 value: function clear() {
300 this._map = new Map();
301 this._arrayTreeMap = new Map();
302 this._objectTreeMap = new Map();
303 }
304 }, {
305 key: "size",
306 get: function get() {
307 return this._map.size;
308 }
309 }]);
310
311 return EquivalentKeyMap;
312 }();
313
314 module.exports = EquivalentKeyMap;
315
316
317 /***/ }),
318
319 /***/ 5619:
320 /***/ ((module) => {
321
322
323
324 // do not edit .js files directly - edit src/index.jst
325
326
327 var envHasBigInt64Array = typeof BigInt64Array !== 'undefined';
328
329
330 module.exports = function equal(a, b) {
331 if (a === b) return true;
332
333 if (a && b && typeof a == 'object' && typeof b == 'object') {
334 if (a.constructor !== b.constructor) return false;
335
336 var length, i, keys;
337 if (Array.isArray(a)) {
338 length = a.length;
339 if (length != b.length) return false;
340 for (i = length; i-- !== 0;)
341 if (!equal(a[i], b[i])) return false;
342 return true;
343 }
344
345
346 if ((a instanceof Map) && (b instanceof Map)) {
347 if (a.size !== b.size) return false;
348 for (i of a.entries())
349 if (!b.has(i[0])) return false;
350 for (i of a.entries())
351 if (!equal(i[1], b.get(i[0]))) return false;
352 return true;
353 }
354
355 if ((a instanceof Set) && (b instanceof Set)) {
356 if (a.size !== b.size) return false;
357 for (i of a.entries())
358 if (!b.has(i[0])) return false;
359 return true;
360 }
361
362 if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {
363 length = a.length;
364 if (length != b.length) return false;
365 for (i = length; i-- !== 0;)
366 if (a[i] !== b[i]) return false;
367 return true;
368 }
369
370
371 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
372 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
373 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
374
375 keys = Object.keys(a);
376 length = keys.length;
377 if (length !== Object.keys(b).length) return false;
378
379 for (i = length; i-- !== 0;)
380 if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
381
382 for (i = length; i-- !== 0;) {
383 var key = keys[i];
384
385 if (!equal(a[key], b[key])) return false;
386 }
387
388 return true;
389 }
390
391 // true if both NaN, false otherwise
392 return a!==a && b!==b;
393 };
394
395
396 /***/ })
397
398 /******/ });
399 /************************************************************************/
400 /******/ // The module cache
401 /******/ var __webpack_module_cache__ = {};
402 /******/
403 /******/ // The require function
404 /******/ function __webpack_require__(moduleId) {
405 /******/ // Check if module is in cache
406 /******/ var cachedModule = __webpack_module_cache__[moduleId];
407 /******/ if (cachedModule !== undefined) {
408 /******/ return cachedModule.exports;
409 /******/ }
410 /******/ // Create a new module (and put it into the cache)
411 /******/ var module = __webpack_module_cache__[moduleId] = {
412 /******/ // no module.id needed
413 /******/ // no module.loaded needed
414 /******/ exports: {}
415 /******/ };
416 /******/
417 /******/ // Execute the module function
418 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
419 /******/
420 /******/ // Return the exports of the module
421 /******/ return module.exports;
422 /******/ }
423 /******/
424 /************************************************************************/
425 /******/ /* webpack/runtime/compat get default export */
426 /******/ (() => {
427 /******/ // getDefaultExport function for compatibility with non-harmony modules
428 /******/ __webpack_require__.n = (module) => {
429 /******/ var getter = module && module.__esModule ?
430 /******/ () => (module['default']) :
431 /******/ () => (module);
432 /******/ __webpack_require__.d(getter, { a: getter });
433 /******/ return getter;
434 /******/ };
435 /******/ })();
436 /******/
437 /******/ /* webpack/runtime/define property getters */
438 /******/ (() => {
439 /******/ // define getter functions for harmony exports
440 /******/ __webpack_require__.d = (exports, definition) => {
441 /******/ for(var key in definition) {
442 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
443 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
444 /******/ }
445 /******/ }
446 /******/ };
447 /******/ })();
448 /******/
449 /******/ /* webpack/runtime/hasOwnProperty shorthand */
450 /******/ (() => {
451 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
452 /******/ })();
453 /******/
454 /******/ /* webpack/runtime/make namespace object */
455 /******/ (() => {
456 /******/ // define __esModule on exports
457 /******/ __webpack_require__.r = (exports) => {
458 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
459 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
460 /******/ }
461 /******/ Object.defineProperty(exports, '__esModule', { value: true });
462 /******/ };
463 /******/ })();
464 /******/
465 /************************************************************************/
466 var __webpack_exports__ = {};
467 // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
468 (() => {
469 // ESM COMPAT FLAG
470 __webpack_require__.r(__webpack_exports__);
471
472 // EXPORTS
473 __webpack_require__.d(__webpack_exports__, {
474 "EntityProvider": () => (/* reexport */ EntityProvider),
475 "__experimentalFetchLinkSuggestions": () => (/* reexport */ _experimental_fetch_link_suggestions),
476 "__experimentalFetchUrlData": () => (/* reexport */ _experimental_fetch_url_data),
477 "__experimentalUseEntityRecord": () => (/* reexport */ __experimentalUseEntityRecord),
478 "__experimentalUseEntityRecords": () => (/* reexport */ __experimentalUseEntityRecords),
479 "__experimentalUseResourcePermissions": () => (/* reexport */ __experimentalUseResourcePermissions),
480 "store": () => (/* binding */ store),
481 "useEntityBlockEditor": () => (/* reexport */ useEntityBlockEditor),
482 "useEntityId": () => (/* reexport */ useEntityId),
483 "useEntityProp": () => (/* reexport */ useEntityProp),
484 "useEntityRecord": () => (/* reexport */ useEntityRecord),
485 "useEntityRecords": () => (/* reexport */ useEntityRecords),
486 "useResourcePermissions": () => (/* reexport */ useResourcePermissions)
487 });
488
489 // NAMESPACE OBJECT: ./packages/core-data/build-module/actions.js
490 var build_module_actions_namespaceObject = {};
491 __webpack_require__.r(build_module_actions_namespaceObject);
492 __webpack_require__.d(build_module_actions_namespaceObject, {
493 "__experimentalBatch": () => (__experimentalBatch),
494 "__experimentalReceiveCurrentGlobalStylesId": () => (__experimentalReceiveCurrentGlobalStylesId),
495 "__experimentalReceiveThemeBaseGlobalStyles": () => (__experimentalReceiveThemeBaseGlobalStyles),
496 "__experimentalReceiveThemeGlobalStyleVariations": () => (__experimentalReceiveThemeGlobalStyleVariations),
497 "__experimentalSaveSpecifiedEntityEdits": () => (__experimentalSaveSpecifiedEntityEdits),
498 "__unstableCreateUndoLevel": () => (__unstableCreateUndoLevel),
499 "addEntities": () => (addEntities),
500 "deleteEntityRecord": () => (deleteEntityRecord),
501 "editEntityRecord": () => (editEntityRecord),
502 "receiveAutosaves": () => (receiveAutosaves),
503 "receiveCurrentTheme": () => (receiveCurrentTheme),
504 "receiveCurrentUser": () => (receiveCurrentUser),
505 "receiveEmbedPreview": () => (receiveEmbedPreview),
506 "receiveEntityRecords": () => (receiveEntityRecords),
507 "receiveNavigationFallbackId": () => (receiveNavigationFallbackId),
508 "receiveThemeGlobalStyleRevisions": () => (receiveThemeGlobalStyleRevisions),
509 "receiveThemeSupports": () => (receiveThemeSupports),
510 "receiveUploadPermissions": () => (receiveUploadPermissions),
511 "receiveUserPermission": () => (receiveUserPermission),
512 "receiveUserQuery": () => (receiveUserQuery),
513 "redo": () => (redo),
514 "saveEditedEntityRecord": () => (saveEditedEntityRecord),
515 "saveEntityRecord": () => (saveEntityRecord),
516 "undo": () => (undo)
517 });
518
519 // NAMESPACE OBJECT: ./packages/core-data/build-module/selectors.js
520 var build_module_selectors_namespaceObject = {};
521 __webpack_require__.r(build_module_selectors_namespaceObject);
522 __webpack_require__.d(build_module_selectors_namespaceObject, {
523 "__experimentalGetCurrentGlobalStylesId": () => (__experimentalGetCurrentGlobalStylesId),
524 "__experimentalGetCurrentThemeBaseGlobalStyles": () => (__experimentalGetCurrentThemeBaseGlobalStyles),
525 "__experimentalGetCurrentThemeGlobalStylesVariations": () => (__experimentalGetCurrentThemeGlobalStylesVariations),
526 "__experimentalGetDirtyEntityRecords": () => (__experimentalGetDirtyEntityRecords),
527 "__experimentalGetEntitiesBeingSaved": () => (__experimentalGetEntitiesBeingSaved),
528 "__experimentalGetEntityRecordNoResolver": () => (__experimentalGetEntityRecordNoResolver),
529 "__experimentalGetTemplateForLink": () => (__experimentalGetTemplateForLink),
530 "canUser": () => (canUser),
531 "canUserEditEntityRecord": () => (canUserEditEntityRecord),
532 "getAuthors": () => (getAuthors),
533 "getAutosave": () => (getAutosave),
534 "getAutosaves": () => (getAutosaves),
535 "getBlockPatternCategories": () => (getBlockPatternCategories),
536 "getBlockPatterns": () => (getBlockPatterns),
537 "getCurrentTheme": () => (getCurrentTheme),
538 "getCurrentThemeGlobalStylesRevisions": () => (getCurrentThemeGlobalStylesRevisions),
539 "getCurrentUser": () => (getCurrentUser),
540 "getEditedEntityRecord": () => (getEditedEntityRecord),
541 "getEmbedPreview": () => (getEmbedPreview),
542 "getEntitiesByKind": () => (getEntitiesByKind),
543 "getEntitiesConfig": () => (getEntitiesConfig),
544 "getEntity": () => (getEntity),
545 "getEntityConfig": () => (getEntityConfig),
546 "getEntityRecord": () => (getEntityRecord),
547 "getEntityRecordEdits": () => (getEntityRecordEdits),
548 "getEntityRecordNonTransientEdits": () => (getEntityRecordNonTransientEdits),
549 "getEntityRecords": () => (getEntityRecords),
550 "getLastEntityDeleteError": () => (getLastEntityDeleteError),
551 "getLastEntitySaveError": () => (getLastEntitySaveError),
552 "getRawEntityRecord": () => (getRawEntityRecord),
553 "getRedoEdit": () => (getRedoEdit),
554 "getReferenceByDistinctEdits": () => (getReferenceByDistinctEdits),
555 "getThemeSupports": () => (getThemeSupports),
556 "getUndoEdit": () => (getUndoEdit),
557 "getUserQueryResults": () => (getUserQueryResults),
558 "hasEditsForEntityRecord": () => (hasEditsForEntityRecord),
559 "hasEntityRecords": () => (hasEntityRecords),
560 "hasFetchedAutosaves": () => (hasFetchedAutosaves),
561 "hasRedo": () => (hasRedo),
562 "hasUndo": () => (hasUndo),
563 "isAutosavingEntityRecord": () => (isAutosavingEntityRecord),
564 "isDeletingEntityRecord": () => (isDeletingEntityRecord),
565 "isPreviewEmbedFallback": () => (isPreviewEmbedFallback),
566 "isRequestingEmbedPreview": () => (isRequestingEmbedPreview),
567 "isSavingEntityRecord": () => (isSavingEntityRecord)
568 });
569
570 // NAMESPACE OBJECT: ./packages/core-data/build-module/resolvers.js
571 var resolvers_namespaceObject = {};
572 __webpack_require__.r(resolvers_namespaceObject);
573 __webpack_require__.d(resolvers_namespaceObject, {
574 "__experimentalGetCurrentGlobalStylesId": () => (resolvers_experimentalGetCurrentGlobalStylesId),
575 "__experimentalGetCurrentThemeBaseGlobalStyles": () => (resolvers_experimentalGetCurrentThemeBaseGlobalStyles),
576 "__experimentalGetCurrentThemeGlobalStylesVariations": () => (resolvers_experimentalGetCurrentThemeGlobalStylesVariations),
577 "__experimentalGetTemplateForLink": () => (resolvers_experimentalGetTemplateForLink),
578 "canUser": () => (resolvers_canUser),
579 "canUserEditEntityRecord": () => (resolvers_canUserEditEntityRecord),
580 "getAuthors": () => (resolvers_getAuthors),
581 "getAutosave": () => (resolvers_getAutosave),
582 "getAutosaves": () => (resolvers_getAutosaves),
583 "getBlockPatternCategories": () => (resolvers_getBlockPatternCategories),
584 "getBlockPatterns": () => (resolvers_getBlockPatterns),
585 "getCurrentTheme": () => (resolvers_getCurrentTheme),
586 "getCurrentThemeGlobalStylesRevisions": () => (resolvers_getCurrentThemeGlobalStylesRevisions),
587 "getCurrentUser": () => (resolvers_getCurrentUser),
588 "getEditedEntityRecord": () => (resolvers_getEditedEntityRecord),
589 "getEmbedPreview": () => (resolvers_getEmbedPreview),
590 "getEntityRecord": () => (resolvers_getEntityRecord),
591 "getEntityRecords": () => (resolvers_getEntityRecords),
592 "getNavigationFallbackId": () => (resolvers_getNavigationFallbackId),
593 "getRawEntityRecord": () => (resolvers_getRawEntityRecord),
594 "getThemeSupports": () => (resolvers_getThemeSupports)
595 });
596
597 ;// CONCATENATED MODULE: external ["wp","data"]
598 const external_wp_data_namespaceObject = window["wp"]["data"];
599 // EXTERNAL MODULE: ./node_modules/fast-deep-equal/es6/index.js
600 var es6 = __webpack_require__(5619);
601 var es6_default = /*#__PURE__*/__webpack_require__.n(es6);
602 ;// CONCATENATED MODULE: external ["wp","compose"]
603 const external_wp_compose_namespaceObject = window["wp"]["compose"];
604 ;// CONCATENATED MODULE: external ["wp","isShallowEqual"]
605 const external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"];
606 var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject);
607 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/if-matching-action.js
608 /** @typedef {import('../types').AnyFunction} AnyFunction */
609
610 /**
611 * A higher-order reducer creator which invokes the original reducer only if
612 * the dispatching action matches the given predicate, **OR** if state is
613 * initializing (undefined).
614 *
615 * @param {AnyFunction} isMatch Function predicate for allowing reducer call.
616 *
617 * @return {AnyFunction} Higher-order reducer.
618 */
619 const ifMatchingAction = isMatch => reducer => (state, action) => {
620 if (state === undefined || isMatch(action)) {
621 return reducer(state, action);
622 }
623
624 return state;
625 };
626
627 /* harmony default export */ const if_matching_action = (ifMatchingAction);
628
629 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/replace-action.js
630 /** @typedef {import('../types').AnyFunction} AnyFunction */
631
632 /**
633 * Higher-order reducer creator which substitutes the action object before
634 * passing to the original reducer.
635 *
636 * @param {AnyFunction} replacer Function mapping original action to replacement.
637 *
638 * @return {AnyFunction} Higher-order reducer.
639 */
640 const replaceAction = replacer => reducer => (state, action) => {
641 return reducer(state, replacer(action));
642 };
643
644 /* harmony default export */ const replace_action = (replaceAction);
645
646 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/conservative-map-item.js
647 /**
648 * External dependencies
649 */
650
651 /**
652 * Given the current and next item entity record, returns the minimally "modified"
653 * result of the next item, preferring value references from the original item
654 * if equal. If all values match, the original item is returned.
655 *
656 * @param {Object} item Original item.
657 * @param {Object} nextItem Next item.
658 *
659 * @return {Object} Minimally modified merged item.
660 */
661
662 function conservativeMapItem(item, nextItem) {
663 // Return next item in its entirety if there is no original item.
664 if (!item) {
665 return nextItem;
666 }
667
668 let hasChanges = false;
669 const result = {};
670
671 for (const key in nextItem) {
672 if (es6_default()(item[key], nextItem[key])) {
673 result[key] = item[key];
674 } else {
675 hasChanges = true;
676 result[key] = nextItem[key];
677 }
678 }
679
680 if (!hasChanges) {
681 return item;
682 } // Only at this point, backfill properties from the original item which
683 // weren't explicitly set into the result above. This is an optimization
684 // to allow `hasChanges` to return early.
685
686
687 for (const key in item) {
688 if (!result.hasOwnProperty(key)) {
689 result[key] = item[key];
690 }
691 }
692
693 return result;
694 }
695
696 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/on-sub-key.js
697 /** @typedef {import('../types').AnyFunction} AnyFunction */
698
699 /**
700 * Higher-order reducer creator which creates a combined reducer object, keyed
701 * by a property on the action object.
702 *
703 * @param {string} actionProperty Action property by which to key object.
704 *
705 * @return {AnyFunction} Higher-order reducer.
706 */
707 const onSubKey = actionProperty => reducer => (state = {}, action) => {
708 // Retrieve subkey from action. Do not track if undefined; useful for cases
709 // where reducer is scoped by action shape.
710 const key = action[actionProperty];
711
712 if (key === undefined) {
713 return state;
714 } // Avoid updating state if unchanged. Note that this also accounts for a
715 // reducer which returns undefined on a key which is not yet tracked.
716
717
718 const nextKeyState = reducer(state[key], action);
719
720 if (nextKeyState === state[key]) {
721 return state;
722 }
723
724 return { ...state,
725 [key]: nextKeyState
726 };
727 };
728 /* harmony default export */ const on_sub_key = (onSubKey);
729
730 ;// CONCATENATED MODULE: ./node_modules/tslib/tslib.es6.js
731 /*! *****************************************************************************
732 Copyright (c) Microsoft Corporation.
733
734 Permission to use, copy, modify, and/or distribute this software for any
735 purpose with or without fee is hereby granted.
736
737 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
738 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
739 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
740 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
741 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
742 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
743 PERFORMANCE OF THIS SOFTWARE.
744 ***************************************************************************** */
745 /* global Reflect, Promise */
746
747 var extendStatics = function(d, b) {
748 extendStatics = Object.setPrototypeOf ||
749 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
750 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
751 return extendStatics(d, b);
752 };
753
754 function __extends(d, b) {
755 if (typeof b !== "function" && b !== null)
756 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
757 extendStatics(d, b);
758 function __() { this.constructor = d; }
759 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
760 }
761
762 var __assign = function() {
763 __assign = Object.assign || function __assign(t) {
764 for (var s, i = 1, n = arguments.length; i < n; i++) {
765 s = arguments[i];
766 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
767 }
768 return t;
769 }
770 return __assign.apply(this, arguments);
771 }
772
773 function __rest(s, e) {
774 var t = {};
775 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
776 t[p] = s[p];
777 if (s != null && typeof Object.getOwnPropertySymbols === "function")
778 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
779 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
780 t[p[i]] = s[p[i]];
781 }
782 return t;
783 }
784
785 function __decorate(decorators, target, key, desc) {
786 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
787 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
788 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
789 return c > 3 && r && Object.defineProperty(target, key, r), r;
790 }
791
792 function __param(paramIndex, decorator) {
793 return function (target, key) { decorator(target, key, paramIndex); }
794 }
795
796 function __metadata(metadataKey, metadataValue) {
797 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
798 }
799
800 function __awaiter(thisArg, _arguments, P, generator) {
801 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
802 return new (P || (P = Promise))(function (resolve, reject) {
803 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
804 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
805 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
806 step((generator = generator.apply(thisArg, _arguments || [])).next());
807 });
808 }
809
810 function __generator(thisArg, body) {
811 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
812 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
813 function verb(n) { return function (v) { return step([n, v]); }; }
814 function step(op) {
815 if (f) throw new TypeError("Generator is already executing.");
816 while (_) try {
817 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
818 if (y = 0, t) op = [op[0] & 2, t.value];
819 switch (op[0]) {
820 case 0: case 1: t = op; break;
821 case 4: _.label++; return { value: op[1], done: false };
822 case 5: _.label++; y = op[1]; op = [0]; continue;
823 case 7: op = _.ops.pop(); _.trys.pop(); continue;
824 default:
825 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
826 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
827 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
828 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
829 if (t[2]) _.ops.pop();
830 _.trys.pop(); continue;
831 }
832 op = body.call(thisArg, _);
833 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
834 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
835 }
836 }
837
838 var __createBinding = Object.create ? (function(o, m, k, k2) {
839 if (k2 === undefined) k2 = k;
840 Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
841 }) : (function(o, m, k, k2) {
842 if (k2 === undefined) k2 = k;
843 o[k2] = m[k];
844 });
845
846 function __exportStar(m, o) {
847 for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);
848 }
849
850 function __values(o) {
851 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
852 if (m) return m.call(o);
853 if (o && typeof o.length === "number") return {
854 next: function () {
855 if (o && i >= o.length) o = void 0;
856 return { value: o && o[i++], done: !o };
857 }
858 };
859 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
860 }
861
862 function __read(o, n) {
863 var m = typeof Symbol === "function" && o[Symbol.iterator];
864 if (!m) return o;
865 var i = m.call(o), r, ar = [], e;
866 try {
867 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
868 }
869 catch (error) { e = { error: error }; }
870 finally {
871 try {
872 if (r && !r.done && (m = i["return"])) m.call(i);
873 }
874 finally { if (e) throw e.error; }
875 }
876 return ar;
877 }
878
879 /** @deprecated */
880 function __spread() {
881 for (var ar = [], i = 0; i < arguments.length; i++)
882 ar = ar.concat(__read(arguments[i]));
883 return ar;
884 }
885
886 /** @deprecated */
887 function __spreadArrays() {
888 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
889 for (var r = Array(s), k = 0, i = 0; i < il; i++)
890 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
891 r[k] = a[j];
892 return r;
893 }
894
895 function __spreadArray(to, from, pack) {
896 if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
897 if (ar || !(i in from)) {
898 if (!ar) ar = Array.prototype.slice.call(from, 0, i);
899 ar[i] = from[i];
900 }
901 }
902 return to.concat(ar || from);
903 }
904
905 function __await(v) {
906 return this instanceof __await ? (this.v = v, this) : new __await(v);
907 }
908
909 function __asyncGenerator(thisArg, _arguments, generator) {
910 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
911 var g = generator.apply(thisArg, _arguments || []), i, q = [];
912 return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
913 function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
914 function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
915 function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
916 function fulfill(value) { resume("next", value); }
917 function reject(value) { resume("throw", value); }
918 function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
919 }
920
921 function __asyncDelegator(o) {
922 var i, p;
923 return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
924 function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
925 }
926
927 function __asyncValues(o) {
928 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
929 var m = o[Symbol.asyncIterator], i;
930 return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
931 function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
932 function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
933 }
934
935 function __makeTemplateObject(cooked, raw) {
936 if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
937 return cooked;
938 };
939
940 var __setModuleDefault = Object.create ? (function(o, v) {
941 Object.defineProperty(o, "default", { enumerable: true, value: v });
942 }) : function(o, v) {
943 o["default"] = v;
944 };
945
946 function __importStar(mod) {
947 if (mod && mod.__esModule) return mod;
948 var result = {};
949 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
950 __setModuleDefault(result, mod);
951 return result;
952 }
953
954 function __importDefault(mod) {
955 return (mod && mod.__esModule) ? mod : { default: mod };
956 }
957
958 function __classPrivateFieldGet(receiver, state, kind, f) {
959 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
960 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
961 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
962 }
963
964 function __classPrivateFieldSet(receiver, state, value, kind, f) {
965 if (kind === "m") throw new TypeError("Private method is not writable");
966 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
967 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
968 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
969 }
970
971 ;// CONCATENATED MODULE: ./node_modules/lower-case/dist.es2015/index.js
972 /**
973 * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
974 */
975 var SUPPORTED_LOCALE = {
976 tr: {
977 regexp: /\u0130|\u0049|\u0049\u0307/g,
978 map: {
979 İ: "\u0069",
980 I: "\u0131",
981 : "\u0069",
982 },
983 },
984 az: {
985 regexp: /\u0130/g,
986 map: {
987 İ: "\u0069",
988 I: "\u0131",
989 : "\u0069",
990 },
991 },
992 lt: {
993 regexp: /\u0049|\u004A|\u012E|\u00CC|\u00CD|\u0128/g,
994 map: {
995 I: "\u0069\u0307",
996 J: "\u006A\u0307",
997 Į: "\u012F\u0307",
998 Ì: "\u0069\u0307\u0300",
999 Í: "\u0069\u0307\u0301",
1000 Ĩ: "\u0069\u0307\u0303",
1001 },
1002 },
1003 };
1004 /**
1005 * Localized lower case.
1006 */
1007 function localeLowerCase(str, locale) {
1008 var lang = SUPPORTED_LOCALE[locale.toLowerCase()];
1009 if (lang)
1010 return lowerCase(str.replace(lang.regexp, function (m) { return lang.map[m]; }));
1011 return lowerCase(str);
1012 }
1013 /**
1014 * Lower case as a function.
1015 */
1016 function lowerCase(str) {
1017 return str.toLowerCase();
1018 }
1019
1020 ;// CONCATENATED MODULE: ./node_modules/no-case/dist.es2015/index.js
1021
1022 // Support camel case ("camelCase" -> "camel Case" and "CAMELCase" -> "CAMEL Case").
1023 var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g];
1024 // Remove all non-word characters.
1025 var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi;
1026 /**
1027 * Normalize the string into something other libraries can manipulate easier.
1028 */
1029 function noCase(input, options) {
1030 if (options === void 0) { options = {}; }
1031 var _a = options.splitRegexp, splitRegexp = _a === void 0 ? DEFAULT_SPLIT_REGEXP : _a, _b = options.stripRegexp, stripRegexp = _b === void 0 ? DEFAULT_STRIP_REGEXP : _b, _c = options.transform, transform = _c === void 0 ? lowerCase : _c, _d = options.delimiter, delimiter = _d === void 0 ? " " : _d;
1032 var result = replace(replace(input, splitRegexp, "$1\0$2"), stripRegexp, "\0");
1033 var start = 0;
1034 var end = result.length;
1035 // Trim the delimiter from around the output string.
1036 while (result.charAt(start) === "\0")
1037 start++;
1038 while (result.charAt(end - 1) === "\0")
1039 end--;
1040 // Transform each token independently.
1041 return result.slice(start, end).split("\0").map(transform).join(delimiter);
1042 }
1043 /**
1044 * Replace `re` in the input string with the replacement value.
1045 */
1046 function replace(input, re, value) {
1047 if (re instanceof RegExp)
1048 return input.replace(re, value);
1049 return re.reduce(function (input, re) { return input.replace(re, value); }, input);
1050 }
1051
1052 ;// CONCATENATED MODULE: ./node_modules/upper-case-first/dist.es2015/index.js
1053 /**
1054 * Upper case the first character of an input string.
1055 */
1056 function upperCaseFirst(input) {
1057 return input.charAt(0).toUpperCase() + input.substr(1);
1058 }
1059
1060 ;// CONCATENATED MODULE: ./node_modules/capital-case/dist.es2015/index.js
1061
1062
1063
1064 function capitalCaseTransform(input) {
1065 return upperCaseFirst(input.toLowerCase());
1066 }
1067 function capitalCase(input, options) {
1068 if (options === void 0) { options = {}; }
1069 return noCase(input, __assign({ delimiter: " ", transform: capitalCaseTransform }, options));
1070 }
1071
1072 ;// CONCATENATED MODULE: ./node_modules/pascal-case/dist.es2015/index.js
1073
1074
1075 function pascalCaseTransform(input, index) {
1076 var firstChar = input.charAt(0);
1077 var lowerChars = input.substr(1).toLowerCase();
1078 if (index > 0 && firstChar >= "0" && firstChar <= "9") {
1079 return "_" + firstChar + lowerChars;
1080 }
1081 return "" + firstChar.toUpperCase() + lowerChars;
1082 }
1083 function dist_es2015_pascalCaseTransformMerge(input) {
1084 return input.charAt(0).toUpperCase() + input.slice(1).toLowerCase();
1085 }
1086 function pascalCase(input, options) {
1087 if (options === void 0) { options = {}; }
1088 return noCase(input, __assign({ delimiter: "", transform: pascalCaseTransform }, options));
1089 }
1090
1091 ;// CONCATENATED MODULE: external ["wp","apiFetch"]
1092 const external_wp_apiFetch_namespaceObject = window["wp"]["apiFetch"];
1093 var external_wp_apiFetch_default = /*#__PURE__*/__webpack_require__.n(external_wp_apiFetch_namespaceObject);
1094 ;// CONCATENATED MODULE: external ["wp","i18n"]
1095 const external_wp_i18n_namespaceObject = window["wp"]["i18n"];
1096 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/rng.js
1097 // Unique ID creation requires a high quality random # generator. In the browser we therefore
1098 // require the crypto API and do not support built-in fallback to lower quality random number
1099 // generators (like Math.random()).
1100 // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
1101 // find the complete implementation of crypto (msCrypto) on IE11.
1102 var getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
1103 var rnds8 = new Uint8Array(16);
1104 function rng() {
1105 if (!getRandomValues) {
1106 throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
1107 }
1108
1109 return getRandomValues(rnds8);
1110 }
1111 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/regex.js
1112 /* harmony default export */ const regex = (/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i);
1113 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/validate.js
1114
1115
1116 function validate(uuid) {
1117 return typeof uuid === 'string' && regex.test(uuid);
1118 }
1119
1120 /* harmony default export */ const esm_browser_validate = (validate);
1121 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/stringify.js
1122
1123 /**
1124 * Convert array of 16 byte values to UUID string format of the form:
1125 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
1126 */
1127
1128 var byteToHex = [];
1129
1130 for (var i = 0; i < 256; ++i) {
1131 byteToHex.push((i + 0x100).toString(16).substr(1));
1132 }
1133
1134 function stringify(arr) {
1135 var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
1136 // Note: Be careful editing this code! It's been tuned for performance
1137 // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
1138 var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one
1139 // of the following:
1140 // - One or more input array values don't map to a hex octet (leading to
1141 // "undefined" in the uuid)
1142 // - Invalid input values for the RFC `version` or `variant` fields
1143
1144 if (!esm_browser_validate(uuid)) {
1145 throw TypeError('Stringified UUID is invalid');
1146 }
1147
1148 return uuid;
1149 }
1150
1151 /* harmony default export */ const esm_browser_stringify = (stringify);
1152 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/v4.js
1153
1154
1155
1156 function v4(options, buf, offset) {
1157 options = options || {};
1158 var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
1159
1160 rnds[6] = rnds[6] & 0x0f | 0x40;
1161 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
1162
1163 if (buf) {
1164 offset = offset || 0;
1165
1166 for (var i = 0; i < 16; ++i) {
1167 buf[offset + i] = rnds[i];
1168 }
1169
1170 return buf;
1171 }
1172
1173 return esm_browser_stringify(rnds);
1174 }
1175
1176 /* harmony default export */ const esm_browser_v4 = (v4);
1177 ;// CONCATENATED MODULE: external ["wp","url"]
1178 const external_wp_url_namespaceObject = window["wp"]["url"];
1179 ;// CONCATENATED MODULE: external ["wp","deprecated"]
1180 const external_wp_deprecated_namespaceObject = window["wp"]["deprecated"];
1181 var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject);
1182 ;// CONCATENATED MODULE: ./packages/core-data/build-module/queried-data/actions.js
1183 /**
1184 * Returns an action object used in signalling that items have been received.
1185 *
1186 * @param {Array} items Items received.
1187 * @param {?Object} edits Optional edits to reset.
1188 *
1189 * @return {Object} Action object.
1190 */
1191 function receiveItems(items, edits) {
1192 return {
1193 type: 'RECEIVE_ITEMS',
1194 items: Array.isArray(items) ? items : [items],
1195 persistedEdits: edits
1196 };
1197 }
1198 /**
1199 * Returns an action object used in signalling that entity records have been
1200 * deleted and they need to be removed from entities state.
1201 *
1202 * @param {string} kind Kind of the removed entities.
1203 * @param {string} name Name of the removed entities.
1204 * @param {Array|number|string} records Record IDs of the removed entities.
1205 * @param {boolean} invalidateCache Controls whether we want to invalidate the cache.
1206 * @return {Object} Action object.
1207 */
1208
1209 function removeItems(kind, name, records, invalidateCache = false) {
1210 return {
1211 type: 'REMOVE_ITEMS',
1212 itemIds: Array.isArray(records) ? records : [records],
1213 kind,
1214 name,
1215 invalidateCache
1216 };
1217 }
1218 /**
1219 * Returns an action object used in signalling that queried data has been
1220 * received.
1221 *
1222 * @param {Array} items Queried items received.
1223 * @param {?Object} query Optional query object.
1224 * @param {?Object} edits Optional edits to reset.
1225 *
1226 * @return {Object} Action object.
1227 */
1228
1229 function receiveQueriedItems(items, query = {}, edits) {
1230 return { ...receiveItems(items, edits),
1231 query
1232 };
1233 }
1234
1235 ;// CONCATENATED MODULE: ./packages/core-data/build-module/batch/default-processor.js
1236 /**
1237 * WordPress dependencies
1238 */
1239
1240 /**
1241 * Maximum number of requests to place in a single batch request. Obtained by
1242 * sending a preflight OPTIONS request to /batch/v1/.
1243 *
1244 * @type {number?}
1245 */
1246
1247 let maxItems = null;
1248
1249 function chunk(arr, chunkSize) {
1250 const tmp = [...arr];
1251 const cache = [];
1252
1253 while (tmp.length) {
1254 cache.push(tmp.splice(0, chunkSize));
1255 }
1256
1257 return cache;
1258 }
1259 /**
1260 * Default batch processor. Sends its input requests to /batch/v1.
1261 *
1262 * @param {Array} requests List of API requests to perform at once.
1263 *
1264 * @return {Promise} Promise that resolves to a list of objects containing
1265 * either `output` (if that request was successful) or `error`
1266 * (if not ).
1267 */
1268
1269
1270 async function defaultProcessor(requests) {
1271 if (maxItems === null) {
1272 const preflightResponse = await external_wp_apiFetch_default()({
1273 path: '/batch/v1',
1274 method: 'OPTIONS'
1275 });
1276 maxItems = preflightResponse.endpoints[0].args.requests.maxItems;
1277 }
1278
1279 const results = []; // @ts-ignore We would have crashed or never gotten to this point if we hadn't received the maxItems count.
1280
1281 for (const batchRequests of chunk(requests, maxItems)) {
1282 const batchResponse = await external_wp_apiFetch_default()({
1283 path: '/batch/v1',
1284 method: 'POST',
1285 data: {
1286 validation: 'require-all-validate',
1287 requests: batchRequests.map(request => ({
1288 path: request.path,
1289 body: request.data,
1290 // Rename 'data' to 'body'.
1291 method: request.method,
1292 headers: request.headers
1293 }))
1294 }
1295 });
1296 let batchResults;
1297
1298 if (batchResponse.failed) {
1299 batchResults = batchResponse.responses.map(response => ({
1300 error: response?.body
1301 }));
1302 } else {
1303 batchResults = batchResponse.responses.map(response => {
1304 const result = {};
1305
1306 if (response.status >= 200 && response.status < 300) {
1307 result.output = response.body;
1308 } else {
1309 result.error = response.body;
1310 }
1311
1312 return result;
1313 });
1314 }
1315
1316 results.push(...batchResults);
1317 }
1318
1319 return results;
1320 }
1321
1322 ;// CONCATENATED MODULE: ./packages/core-data/build-module/batch/create-batch.js
1323 /**
1324 * Internal dependencies
1325 */
1326
1327 /**
1328 * Creates a batch, which can be used to combine multiple API requests into one
1329 * API request using the WordPress batch processing API (/v1/batch).
1330 *
1331 * ```
1332 * const batch = createBatch();
1333 * const dunePromise = batch.add( {
1334 * path: '/v1/books',
1335 * method: 'POST',
1336 * data: { title: 'Dune' }
1337 * } );
1338 * const lotrPromise = batch.add( {
1339 * path: '/v1/books',
1340 * method: 'POST',
1341 * data: { title: 'Lord of the Rings' }
1342 * } );
1343 * const isSuccess = await batch.run(); // Sends one POST to /v1/batch.
1344 * if ( isSuccess ) {
1345 * console.log(
1346 * 'Saved two books:',
1347 * await dunePromise,
1348 * await lotrPromise
1349 * );
1350 * }
1351 * ```
1352 *
1353 * @param {Function} [processor] Processor function. Can be used to replace the
1354 * default functionality which is to send an API
1355 * request to /v1/batch. Is given an array of
1356 * inputs and must return a promise that
1357 * resolves to an array of objects containing
1358 * either `output` or `error`.
1359 */
1360
1361 function createBatch(processor = defaultProcessor) {
1362 let lastId = 0;
1363 /** @type {Array<{ input: any; resolve: ( value: any ) => void; reject: ( error: any ) => void }>} */
1364
1365 let queue = [];
1366 const pending = new ObservableSet();
1367 return {
1368 /**
1369 * Adds an input to the batch and returns a promise that is resolved or
1370 * rejected when the input is processed by `batch.run()`.
1371 *
1372 * You may also pass a thunk which allows inputs to be added
1373 * asychronously.
1374 *
1375 * ```
1376 * // Both are allowed:
1377 * batch.add( { path: '/v1/books', ... } );
1378 * batch.add( ( add ) => add( { path: '/v1/books', ... } ) );
1379 * ```
1380 *
1381 * If a thunk is passed, `batch.run()` will pause until either:
1382 *
1383 * - The thunk calls its `add` argument, or;
1384 * - The thunk returns a promise and that promise resolves, or;
1385 * - The thunk returns a non-promise.
1386 *
1387 * @param {any|Function} inputOrThunk Input to add or thunk to execute.
1388 *
1389 * @return {Promise|any} If given an input, returns a promise that
1390 * is resolved or rejected when the batch is
1391 * processed. If given a thunk, returns the return
1392 * value of that thunk.
1393 */
1394 add(inputOrThunk) {
1395 const id = ++lastId;
1396 pending.add(id);
1397
1398 const add = input => new Promise((resolve, reject) => {
1399 queue.push({
1400 input,
1401 resolve,
1402 reject
1403 });
1404 pending.delete(id);
1405 });
1406
1407 if (typeof inputOrThunk === 'function') {
1408 return Promise.resolve(inputOrThunk(add)).finally(() => {
1409 pending.delete(id);
1410 });
1411 }
1412
1413 return add(inputOrThunk);
1414 },
1415
1416 /**
1417 * Runs the batch. This calls `batchProcessor` and resolves or rejects
1418 * all promises returned by `add()`.
1419 *
1420 * @return {Promise<boolean>} A promise that resolves to a boolean that is true
1421 * if the processor returned no errors.
1422 */
1423 async run() {
1424 if (pending.size) {
1425 await new Promise(resolve => {
1426 const unsubscribe = pending.subscribe(() => {
1427 if (!pending.size) {
1428 unsubscribe();
1429 resolve(undefined);
1430 }
1431 });
1432 });
1433 }
1434
1435 let results;
1436
1437 try {
1438 results = await processor(queue.map(({
1439 input
1440 }) => input));
1441
1442 if (results.length !== queue.length) {
1443 throw new Error('run: Array returned by processor must be same size as input array.');
1444 }
1445 } catch (error) {
1446 for (const {
1447 reject
1448 } of queue) {
1449 reject(error);
1450 }
1451
1452 throw error;
1453 }
1454
1455 let isSuccess = true;
1456 results.forEach((result, key) => {
1457 const queueItem = queue[key];
1458
1459 if (result?.error) {
1460 queueItem?.reject(result.error);
1461 isSuccess = false;
1462 } else {
1463 var _result$output;
1464
1465 queueItem?.resolve((_result$output = result?.output) !== null && _result$output !== void 0 ? _result$output : result);
1466 }
1467 });
1468 queue = [];
1469 return isSuccess;
1470 }
1471
1472 };
1473 }
1474
1475 class ObservableSet {
1476 constructor(...args) {
1477 this.set = new Set(...args);
1478 this.subscribers = new Set();
1479 }
1480
1481 get size() {
1482 return this.set.size;
1483 }
1484
1485 add(value) {
1486 this.set.add(value);
1487 this.subscribers.forEach(subscriber => subscriber());
1488 return this;
1489 }
1490
1491 delete(value) {
1492 const isSuccess = this.set.delete(value);
1493 this.subscribers.forEach(subscriber => subscriber());
1494 return isSuccess;
1495 }
1496
1497 subscribe(subscriber) {
1498 this.subscribers.add(subscriber);
1499 return () => {
1500 this.subscribers.delete(subscriber);
1501 };
1502 }
1503
1504 }
1505
1506 ;// CONCATENATED MODULE: ./packages/core-data/build-module/name.js
1507 /**
1508 * The reducer key used by core data in store registration.
1509 * This is defined in a separate file to avoid cycle-dependency
1510 *
1511 * @type {string}
1512 */
1513 const STORE_NAME = 'core';
1514
1515 ;// CONCATENATED MODULE: ./packages/core-data/build-module/private-selectors.js
1516 /**
1517 * Internal dependencies
1518 */
1519
1520 /**
1521 * Returns the previous edit from the current undo offset
1522 * for the entity records edits history, if any.
1523 *
1524 * @param state State tree.
1525 *
1526 * @return The edit.
1527 */
1528 function getUndoEdits(state) {
1529 return state.undo.list[state.undo.list.length - 1 + state.undo.offset];
1530 }
1531 /**
1532 * Returns the next edit from the current undo offset
1533 * for the entity records edits history, if any.
1534 *
1535 * @param state State tree.
1536 *
1537 * @return The edit.
1538 */
1539
1540 function getRedoEdits(state) {
1541 return state.undo.list[state.undo.list.length + state.undo.offset];
1542 }
1543 /**
1544 * Retrieve the fallback Navigation.
1545 *
1546 * @param state Data state.
1547 * @return The ID for the fallback Navigation post.
1548 */
1549
1550 function getNavigationFallbackId(state) {
1551 return state.navigationFallbackId;
1552 }
1553
1554 ;// CONCATENATED MODULE: ./packages/core-data/build-module/actions.js
1555 /**
1556 * External dependencies
1557 */
1558
1559
1560 /**
1561 * WordPress dependencies
1562 */
1563
1564
1565
1566
1567 /**
1568 * Internal dependencies
1569 */
1570
1571
1572
1573
1574
1575
1576 /**
1577 * Returns an action object used in signalling that authors have been received.
1578 * Ignored from documentation as it's internal to the data store.
1579 *
1580 * @ignore
1581 *
1582 * @param {string} queryID Query ID.
1583 * @param {Array|Object} users Users received.
1584 *
1585 * @return {Object} Action object.
1586 */
1587
1588 function receiveUserQuery(queryID, users) {
1589 return {
1590 type: 'RECEIVE_USER_QUERY',
1591 users: Array.isArray(users) ? users : [users],
1592 queryID
1593 };
1594 }
1595 /**
1596 * Returns an action used in signalling that the current user has been received.
1597 * Ignored from documentation as it's internal to the data store.
1598 *
1599 * @ignore
1600 *
1601 * @param {Object} currentUser Current user object.
1602 *
1603 * @return {Object} Action object.
1604 */
1605
1606 function receiveCurrentUser(currentUser) {
1607 return {
1608 type: 'RECEIVE_CURRENT_USER',
1609 currentUser
1610 };
1611 }
1612 /**
1613 * Returns an action object used in adding new entities.
1614 *
1615 * @param {Array} entities Entities received.
1616 *
1617 * @return {Object} Action object.
1618 */
1619
1620 function addEntities(entities) {
1621 return {
1622 type: 'ADD_ENTITIES',
1623 entities
1624 };
1625 }
1626 /**
1627 * Returns an action object used in signalling that entity records have been received.
1628 *
1629 * @param {string} kind Kind of the received entity record.
1630 * @param {string} name Name of the received entity record.
1631 * @param {Array|Object} records Records received.
1632 * @param {?Object} query Query Object.
1633 * @param {?boolean} invalidateCache Should invalidate query caches.
1634 * @param {?Object} edits Edits to reset.
1635 * @return {Object} Action object.
1636 */
1637
1638 function receiveEntityRecords(kind, name, records, query, invalidateCache = false, edits) {
1639 // Auto drafts should not have titles, but some plugins rely on them so we can't filter this
1640 // on the server.
1641 if (kind === 'postType') {
1642 records = (Array.isArray(records) ? records : [records]).map(record => record.status === 'auto-draft' ? { ...record,
1643 title: ''
1644 } : record);
1645 }
1646
1647 let action;
1648
1649 if (query) {
1650 action = receiveQueriedItems(records, query, edits);
1651 } else {
1652 action = receiveItems(records, edits);
1653 }
1654
1655 return { ...action,
1656 kind,
1657 name,
1658 invalidateCache
1659 };
1660 }
1661 /**
1662 * Returns an action object used in signalling that the current theme has been received.
1663 * Ignored from documentation as it's internal to the data store.
1664 *
1665 * @ignore
1666 *
1667 * @param {Object} currentTheme The current theme.
1668 *
1669 * @return {Object} Action object.
1670 */
1671
1672 function receiveCurrentTheme(currentTheme) {
1673 return {
1674 type: 'RECEIVE_CURRENT_THEME',
1675 currentTheme
1676 };
1677 }
1678 /**
1679 * Returns an action object used in signalling that the current global styles id has been received.
1680 * Ignored from documentation as it's internal to the data store.
1681 *
1682 * @ignore
1683 *
1684 * @param {string} currentGlobalStylesId The current global styles id.
1685 *
1686 * @return {Object} Action object.
1687 */
1688
1689 function __experimentalReceiveCurrentGlobalStylesId(currentGlobalStylesId) {
1690 return {
1691 type: 'RECEIVE_CURRENT_GLOBAL_STYLES_ID',
1692 id: currentGlobalStylesId
1693 };
1694 }
1695 /**
1696 * Returns an action object used in signalling that the theme base global styles have been received
1697 * Ignored from documentation as it's internal to the data store.
1698 *
1699 * @ignore
1700 *
1701 * @param {string} stylesheet The theme's identifier
1702 * @param {Object} globalStyles The global styles object.
1703 *
1704 * @return {Object} Action object.
1705 */
1706
1707 function __experimentalReceiveThemeBaseGlobalStyles(stylesheet, globalStyles) {
1708 return {
1709 type: 'RECEIVE_THEME_GLOBAL_STYLES',
1710 stylesheet,
1711 globalStyles
1712 };
1713 }
1714 /**
1715 * Returns an action object used in signalling that the theme global styles variations have been received.
1716 * Ignored from documentation as it's internal to the data store.
1717 *
1718 * @ignore
1719 *
1720 * @param {string} stylesheet The theme's identifier
1721 * @param {Array} variations The global styles variations.
1722 *
1723 * @return {Object} Action object.
1724 */
1725
1726 function __experimentalReceiveThemeGlobalStyleVariations(stylesheet, variations) {
1727 return {
1728 type: 'RECEIVE_THEME_GLOBAL_STYLE_VARIATIONS',
1729 stylesheet,
1730 variations
1731 };
1732 }
1733 /**
1734 * Returns an action object used in signalling that the index has been received.
1735 *
1736 * @deprecated since WP 5.9, this is not useful anymore, use the selector direclty.
1737 *
1738 * @return {Object} Action object.
1739 */
1740
1741 function receiveThemeSupports() {
1742 external_wp_deprecated_default()("wp.data.dispatch( 'core' ).receiveThemeSupports", {
1743 since: '5.9'
1744 });
1745 return {
1746 type: 'DO_NOTHING'
1747 };
1748 }
1749 /**
1750 * Returns an action object used in signalling that the theme global styles CPT post revisions have been received.
1751 * Ignored from documentation as it's internal to the data store.
1752 *
1753 * @ignore
1754 *
1755 * @param {number} currentId The post id.
1756 * @param {Array} revisions The global styles revisions.
1757 *
1758 * @return {Object} Action object.
1759 */
1760
1761 function receiveThemeGlobalStyleRevisions(currentId, revisions) {
1762 return {
1763 type: 'RECEIVE_THEME_GLOBAL_STYLE_REVISIONS',
1764 currentId,
1765 revisions
1766 };
1767 }
1768 /**
1769 * Returns an action object used in signalling that the preview data for
1770 * a given URl has been received.
1771 * Ignored from documentation as it's internal to the data store.
1772 *
1773 * @ignore
1774 *
1775 * @param {string} url URL to preview the embed for.
1776 * @param {*} preview Preview data.
1777 *
1778 * @return {Object} Action object.
1779 */
1780
1781 function receiveEmbedPreview(url, preview) {
1782 return {
1783 type: 'RECEIVE_EMBED_PREVIEW',
1784 url,
1785 preview
1786 };
1787 }
1788 /**
1789 * Action triggered to delete an entity record.
1790 *
1791 * @param {string} kind Kind of the deleted entity.
1792 * @param {string} name Name of the deleted entity.
1793 * @param {string} recordId Record ID of the deleted entity.
1794 * @param {?Object} query Special query parameters for the
1795 * DELETE API call.
1796 * @param {Object} [options] Delete options.
1797 * @param {Function} [options.__unstableFetch] Internal use only. Function to
1798 * call instead of `apiFetch()`.
1799 * Must return a promise.
1800 * @param {boolean} [options.throwOnError=false] If false, this action suppresses all
1801 * the exceptions. Defaults to false.
1802 */
1803
1804 const deleteEntityRecord = (kind, name, recordId, query, {
1805 __unstableFetch = (external_wp_apiFetch_default()),
1806 throwOnError = false
1807 } = {}) => async ({
1808 dispatch
1809 }) => {
1810 const configs = await dispatch(getOrLoadEntitiesConfig(kind));
1811 const entityConfig = configs.find(config => config.kind === kind && config.name === name);
1812 let error;
1813 let deletedRecord = false;
1814
1815 if (!entityConfig || entityConfig?.__experimentalNoFetch) {
1816 return;
1817 }
1818
1819 const lock = await dispatch.__unstableAcquireStoreLock(STORE_NAME, ['entities', 'records', kind, name, recordId], {
1820 exclusive: true
1821 });
1822
1823 try {
1824 dispatch({
1825 type: 'DELETE_ENTITY_RECORD_START',
1826 kind,
1827 name,
1828 recordId
1829 });
1830 let hasError = false;
1831
1832 try {
1833 let path = `${entityConfig.baseURL}/${recordId}`;
1834
1835 if (query) {
1836 path = (0,external_wp_url_namespaceObject.addQueryArgs)(path, query);
1837 }
1838
1839 deletedRecord = await __unstableFetch({
1840 path,
1841 method: 'DELETE'
1842 });
1843 await dispatch(removeItems(kind, name, recordId, true));
1844 } catch (_error) {
1845 hasError = true;
1846 error = _error;
1847 }
1848
1849 dispatch({
1850 type: 'DELETE_ENTITY_RECORD_FINISH',
1851 kind,
1852 name,
1853 recordId,
1854 error
1855 });
1856
1857 if (hasError && throwOnError) {
1858 throw error;
1859 }
1860
1861 return deletedRecord;
1862 } finally {
1863 dispatch.__unstableReleaseStoreLock(lock);
1864 }
1865 };
1866 /**
1867 * Returns an action object that triggers an
1868 * edit to an entity record.
1869 *
1870 * @param {string} kind Kind of the edited entity record.
1871 * @param {string} name Name of the edited entity record.
1872 * @param {number|string} recordId Record ID of the edited entity record.
1873 * @param {Object} edits The edits.
1874 * @param {Object} options Options for the edit.
1875 * @param {boolean} [options.undoIgnore] Whether to ignore the edit in undo history or not.
1876 *
1877 * @return {Object} Action object.
1878 */
1879
1880 const editEntityRecord = (kind, name, recordId, edits, options = {}) => ({
1881 select,
1882 dispatch
1883 }) => {
1884 const entityConfig = select.getEntityConfig(kind, name);
1885
1886 if (!entityConfig) {
1887 throw new Error(`The entity being edited (${kind}, ${name}) does not have a loaded config.`);
1888 }
1889
1890 const {
1891 mergedEdits = {}
1892 } = entityConfig;
1893 const record = select.getRawEntityRecord(kind, name, recordId);
1894 const editedRecord = select.getEditedEntityRecord(kind, name, recordId);
1895 const edit = {
1896 kind,
1897 name,
1898 recordId,
1899 // Clear edits when they are equal to their persisted counterparts
1900 // so that the property is not considered dirty.
1901 edits: Object.keys(edits).reduce((acc, key) => {
1902 const recordValue = record[key];
1903 const editedRecordValue = editedRecord[key];
1904 const value = mergedEdits[key] ? { ...editedRecordValue,
1905 ...edits[key]
1906 } : edits[key];
1907 acc[key] = es6_default()(recordValue, value) ? undefined : value;
1908 return acc;
1909 }, {})
1910 };
1911 dispatch({
1912 type: 'EDIT_ENTITY_RECORD',
1913 ...edit,
1914 meta: {
1915 undo: !options.undoIgnore && { ...edit,
1916 // Send the current values for things like the first undo stack entry.
1917 edits: Object.keys(edits).reduce((acc, key) => {
1918 acc[key] = editedRecord[key];
1919 return acc;
1920 }, {}),
1921 isCached: options.isCached
1922 }
1923 }
1924 });
1925 };
1926 /**
1927 * Action triggered to undo the last edit to
1928 * an entity record, if any.
1929 */
1930
1931 const undo = () => ({
1932 select,
1933 dispatch
1934 }) => {
1935 // Todo: we shouldn't have to pass "root" here.
1936 const undoEdit = select(state => getUndoEdits(state.root));
1937
1938 if (!undoEdit) {
1939 return;
1940 }
1941
1942 dispatch({
1943 type: 'UNDO',
1944 stackedEdits: undoEdit
1945 });
1946 };
1947 /**
1948 * Action triggered to redo the last undoed
1949 * edit to an entity record, if any.
1950 */
1951
1952 const redo = () => ({
1953 select,
1954 dispatch
1955 }) => {
1956 // Todo: we shouldn't have to pass "root" here.
1957 const redoEdit = select(state => getRedoEdits(state.root));
1958
1959 if (!redoEdit) {
1960 return;
1961 }
1962
1963 dispatch({
1964 type: 'REDO',
1965 stackedEdits: redoEdit
1966 });
1967 };
1968 /**
1969 * Forces the creation of a new undo level.
1970 *
1971 * @return {Object} Action object.
1972 */
1973
1974 function __unstableCreateUndoLevel() {
1975 return {
1976 type: 'CREATE_UNDO_LEVEL'
1977 };
1978 }
1979 /**
1980 * Action triggered to save an entity record.
1981 *
1982 * @param {string} kind Kind of the received entity.
1983 * @param {string} name Name of the received entity.
1984 * @param {Object} record Record to be saved.
1985 * @param {Object} options Saving options.
1986 * @param {boolean} [options.isAutosave=false] Whether this is an autosave.
1987 * @param {Function} [options.__unstableFetch] Internal use only. Function to
1988 * call instead of `apiFetch()`.
1989 * Must return a promise.
1990 * @param {boolean} [options.throwOnError=false] If false, this action suppresses all
1991 * the exceptions. Defaults to false.
1992 */
1993
1994 const saveEntityRecord = (kind, name, record, {
1995 isAutosave = false,
1996 __unstableFetch = (external_wp_apiFetch_default()),
1997 throwOnError = false
1998 } = {}) => async ({
1999 select,
2000 resolveSelect,
2001 dispatch
2002 }) => {
2003 const configs = await dispatch(getOrLoadEntitiesConfig(kind));
2004 const entityConfig = configs.find(config => config.kind === kind && config.name === name);
2005
2006 if (!entityConfig || entityConfig?.__experimentalNoFetch) {
2007 return;
2008 }
2009
2010 const entityIdKey = entityConfig.key || DEFAULT_ENTITY_KEY;
2011 const recordId = record[entityIdKey];
2012 const lock = await dispatch.__unstableAcquireStoreLock(STORE_NAME, ['entities', 'records', kind, name, recordId || esm_browser_v4()], {
2013 exclusive: true
2014 });
2015
2016 try {
2017 // Evaluate optimized edits.
2018 // (Function edits that should be evaluated on save to avoid expensive computations on every edit.)
2019 for (const [key, value] of Object.entries(record)) {
2020 if (typeof value === 'function') {
2021 const evaluatedValue = value(select.getEditedEntityRecord(kind, name, recordId));
2022 dispatch.editEntityRecord(kind, name, recordId, {
2023 [key]: evaluatedValue
2024 }, {
2025 undoIgnore: true
2026 });
2027 record[key] = evaluatedValue;
2028 }
2029 }
2030
2031 dispatch({
2032 type: 'SAVE_ENTITY_RECORD_START',
2033 kind,
2034 name,
2035 recordId,
2036 isAutosave
2037 });
2038 let updatedRecord;
2039 let error;
2040 let hasError = false;
2041
2042 try {
2043 const path = `${entityConfig.baseURL}${recordId ? '/' + recordId : ''}`;
2044 const persistedRecord = select.getRawEntityRecord(kind, name, recordId);
2045
2046 if (isAutosave) {
2047 // Most of this autosave logic is very specific to posts.
2048 // This is fine for now as it is the only supported autosave,
2049 // but ideally this should all be handled in the back end,
2050 // so the client just sends and receives objects.
2051 const currentUser = select.getCurrentUser();
2052 const currentUserId = currentUser ? currentUser.id : undefined;
2053 const autosavePost = await resolveSelect.getAutosave(persistedRecord.type, persistedRecord.id, currentUserId); // Autosaves need all expected fields to be present.
2054 // So we fallback to the previous autosave and then
2055 // to the actual persisted entity if the edits don't
2056 // have a value.
2057
2058 let data = { ...persistedRecord,
2059 ...autosavePost,
2060 ...record
2061 };
2062 data = Object.keys(data).reduce((acc, key) => {
2063 if (['title', 'excerpt', 'content'].includes(key)) {
2064 acc[key] = data[key];
2065 }
2066
2067 return acc;
2068 }, {
2069 status: data.status === 'auto-draft' ? 'draft' : data.status
2070 });
2071 updatedRecord = await __unstableFetch({
2072 path: `${path}/autosaves`,
2073 method: 'POST',
2074 data
2075 }); // An autosave may be processed by the server as a regular save
2076 // when its update is requested by the author and the post had
2077 // draft or auto-draft status.
2078
2079 if (persistedRecord.id === updatedRecord.id) {
2080 let newRecord = { ...persistedRecord,
2081 ...data,
2082 ...updatedRecord
2083 };
2084 newRecord = Object.keys(newRecord).reduce((acc, key) => {
2085 // These properties are persisted in autosaves.
2086 if (['title', 'excerpt', 'content'].includes(key)) {
2087 acc[key] = newRecord[key];
2088 } else if (key === 'status') {
2089 // Status is only persisted in autosaves when going from
2090 // "auto-draft" to "draft".
2091 acc[key] = persistedRecord.status === 'auto-draft' && newRecord.status === 'draft' ? newRecord.status : persistedRecord.status;
2092 } else {
2093 // These properties are not persisted in autosaves.
2094 acc[key] = persistedRecord[key];
2095 }
2096
2097 return acc;
2098 }, {});
2099 dispatch.receiveEntityRecords(kind, name, newRecord, undefined, true);
2100 } else {
2101 dispatch.receiveAutosaves(persistedRecord.id, updatedRecord);
2102 }
2103 } else {
2104 let edits = record;
2105
2106 if (entityConfig.__unstablePrePersist) {
2107 edits = { ...edits,
2108 ...entityConfig.__unstablePrePersist(persistedRecord, edits)
2109 };
2110 }
2111
2112 updatedRecord = await __unstableFetch({
2113 path,
2114 method: recordId ? 'PUT' : 'POST',
2115 data: edits
2116 });
2117 dispatch.receiveEntityRecords(kind, name, updatedRecord, undefined, true, edits);
2118 }
2119 } catch (_error) {
2120 hasError = true;
2121 error = _error;
2122 }
2123
2124 dispatch({
2125 type: 'SAVE_ENTITY_RECORD_FINISH',
2126 kind,
2127 name,
2128 recordId,
2129 error,
2130 isAutosave
2131 });
2132
2133 if (hasError && throwOnError) {
2134 throw error;
2135 }
2136
2137 return updatedRecord;
2138 } finally {
2139 dispatch.__unstableReleaseStoreLock(lock);
2140 }
2141 };
2142 /**
2143 * Runs multiple core-data actions at the same time using one API request.
2144 *
2145 * Example:
2146 *
2147 * ```
2148 * const [ savedRecord, updatedRecord, deletedRecord ] =
2149 * await dispatch( 'core' ).__experimentalBatch( [
2150 * ( { saveEntityRecord } ) => saveEntityRecord( 'root', 'widget', widget ),
2151 * ( { saveEditedEntityRecord } ) => saveEntityRecord( 'root', 'widget', 123 ),
2152 * ( { deleteEntityRecord } ) => deleteEntityRecord( 'root', 'widget', 123, null ),
2153 * ] );
2154 * ```
2155 *
2156 * @param {Array} requests Array of functions which are invoked simultaneously.
2157 * Each function is passed an object containing
2158 * `saveEntityRecord`, `saveEditedEntityRecord`, and
2159 * `deleteEntityRecord`.
2160 *
2161 * @return {(thunkArgs: Object) => Promise} A promise that resolves to an array containing the return
2162 * values of each function given in `requests`.
2163 */
2164
2165 const __experimentalBatch = requests => async ({
2166 dispatch
2167 }) => {
2168 const batch = createBatch();
2169 const api = {
2170 saveEntityRecord(kind, name, record, options) {
2171 return batch.add(add => dispatch.saveEntityRecord(kind, name, record, { ...options,
2172 __unstableFetch: add
2173 }));
2174 },
2175
2176 saveEditedEntityRecord(kind, name, recordId, options) {
2177 return batch.add(add => dispatch.saveEditedEntityRecord(kind, name, recordId, { ...options,
2178 __unstableFetch: add
2179 }));
2180 },
2181
2182 deleteEntityRecord(kind, name, recordId, query, options) {
2183 return batch.add(add => dispatch.deleteEntityRecord(kind, name, recordId, query, { ...options,
2184 __unstableFetch: add
2185 }));
2186 }
2187
2188 };
2189 const resultPromises = requests.map(request => request(api));
2190 const [, ...results] = await Promise.all([batch.run(), ...resultPromises]);
2191 return results;
2192 };
2193 /**
2194 * Action triggered to save an entity record's edits.
2195 *
2196 * @param {string} kind Kind of the entity.
2197 * @param {string} name Name of the entity.
2198 * @param {Object} recordId ID of the record.
2199 * @param {Object} options Saving options.
2200 */
2201
2202 const saveEditedEntityRecord = (kind, name, recordId, options) => async ({
2203 select,
2204 dispatch
2205 }) => {
2206 if (!select.hasEditsForEntityRecord(kind, name, recordId)) {
2207 return;
2208 }
2209
2210 const configs = await dispatch(getOrLoadEntitiesConfig(kind));
2211 const entityConfig = configs.find(config => config.kind === kind && config.name === name);
2212
2213 if (!entityConfig) {
2214 return;
2215 }
2216
2217 const entityIdKey = entityConfig.key || DEFAULT_ENTITY_KEY;
2218 const edits = select.getEntityRecordNonTransientEdits(kind, name, recordId);
2219 const record = {
2220 [entityIdKey]: recordId,
2221 ...edits
2222 };
2223 return await dispatch.saveEntityRecord(kind, name, record, options);
2224 };
2225 /**
2226 * Action triggered to save only specified properties for the entity.
2227 *
2228 * @param {string} kind Kind of the entity.
2229 * @param {string} name Name of the entity.
2230 * @param {Object} recordId ID of the record.
2231 * @param {Array} itemsToSave List of entity properties to save.
2232 * @param {Object} options Saving options.
2233 */
2234
2235 const __experimentalSaveSpecifiedEntityEdits = (kind, name, recordId, itemsToSave, options) => async ({
2236 select,
2237 dispatch
2238 }) => {
2239 if (!select.hasEditsForEntityRecord(kind, name, recordId)) {
2240 return;
2241 }
2242
2243 const edits = select.getEntityRecordNonTransientEdits(kind, name, recordId);
2244 const editsToSave = {};
2245
2246 for (const edit in edits) {
2247 if (itemsToSave.some(item => item === edit)) {
2248 editsToSave[edit] = edits[edit];
2249 }
2250 }
2251
2252 return await dispatch.saveEntityRecord(kind, name, editsToSave, options);
2253 };
2254 /**
2255 * Returns an action object used in signalling that Upload permissions have been received.
2256 *
2257 * @deprecated since WP 5.9, use receiveUserPermission instead.
2258 *
2259 * @param {boolean} hasUploadPermissions Does the user have permission to upload files?
2260 *
2261 * @return {Object} Action object.
2262 */
2263
2264 function receiveUploadPermissions(hasUploadPermissions) {
2265 external_wp_deprecated_default()("wp.data.dispatch( 'core' ).receiveUploadPermissions", {
2266 since: '5.9',
2267 alternative: 'receiveUserPermission'
2268 });
2269 return receiveUserPermission('create/media', hasUploadPermissions);
2270 }
2271 /**
2272 * Returns an action object used in signalling that the current user has
2273 * permission to perform an action on a REST resource.
2274 * Ignored from documentation as it's internal to the data store.
2275 *
2276 * @ignore
2277 *
2278 * @param {string} key A key that represents the action and REST resource.
2279 * @param {boolean} isAllowed Whether or not the user can perform the action.
2280 *
2281 * @return {Object} Action object.
2282 */
2283
2284 function receiveUserPermission(key, isAllowed) {
2285 return {
2286 type: 'RECEIVE_USER_PERMISSION',
2287 key,
2288 isAllowed
2289 };
2290 }
2291 /**
2292 * Returns an action object used in signalling that the autosaves for a
2293 * post have been received.
2294 * Ignored from documentation as it's internal to the data store.
2295 *
2296 * @ignore
2297 *
2298 * @param {number} postId The id of the post that is parent to the autosave.
2299 * @param {Array|Object} autosaves An array of autosaves or singular autosave object.
2300 *
2301 * @return {Object} Action object.
2302 */
2303
2304 function receiveAutosaves(postId, autosaves) {
2305 return {
2306 type: 'RECEIVE_AUTOSAVES',
2307 postId,
2308 autosaves: Array.isArray(autosaves) ? autosaves : [autosaves]
2309 };
2310 }
2311 /**
2312 * Returns an action object signalling that the fallback Navigation
2313 * Menu id has been received.
2314 *
2315 * @param {integer} fallbackId the id of the fallback Navigation Menu
2316 * @return {Object} Action object.
2317 */
2318
2319 function receiveNavigationFallbackId(fallbackId) {
2320 return {
2321 type: 'RECEIVE_NAVIGATION_FALLBACK_ID',
2322 fallbackId
2323 };
2324 }
2325
2326 ;// CONCATENATED MODULE: ./packages/core-data/build-module/entities.js
2327 /**
2328 * External dependencies
2329 */
2330
2331 /**
2332 * WordPress dependencies
2333 */
2334
2335
2336
2337 /**
2338 * Internal dependencies
2339 */
2340
2341
2342 const DEFAULT_ENTITY_KEY = 'id';
2343 const POST_RAW_ATTRIBUTES = ['title', 'excerpt', 'content'];
2344 const rootEntitiesConfig = [{
2345 label: (0,external_wp_i18n_namespaceObject.__)('Base'),
2346 kind: 'root',
2347 name: '__unstableBase',
2348 baseURL: '/',
2349 baseURLParams: {
2350 _fields: ['description', 'gmt_offset', 'home', 'name', 'site_icon', 'site_icon_url', 'site_logo', 'timezone_string', 'url'].join(',')
2351 }
2352 }, {
2353 label: (0,external_wp_i18n_namespaceObject.__)('Site'),
2354 name: 'site',
2355 kind: 'root',
2356 baseURL: '/wp/v2/settings',
2357 getTitle: record => {
2358 var _record$title;
2359
2360 return (_record$title = record?.title) !== null && _record$title !== void 0 ? _record$title : (0,external_wp_i18n_namespaceObject.__)('Site Title');
2361 }
2362 }, {
2363 label: (0,external_wp_i18n_namespaceObject.__)('Post Type'),
2364 name: 'postType',
2365 kind: 'root',
2366 key: 'slug',
2367 baseURL: '/wp/v2/types',
2368 baseURLParams: {
2369 context: 'edit'
2370 }
2371 }, {
2372 name: 'media',
2373 kind: 'root',
2374 baseURL: '/wp/v2/media',
2375 baseURLParams: {
2376 context: 'edit'
2377 },
2378 plural: 'mediaItems',
2379 label: (0,external_wp_i18n_namespaceObject.__)('Media'),
2380 rawAttributes: ['caption', 'title', 'description']
2381 }, {
2382 name: 'taxonomy',
2383 kind: 'root',
2384 key: 'slug',
2385 baseURL: '/wp/v2/taxonomies',
2386 baseURLParams: {
2387 context: 'edit'
2388 },
2389 plural: 'taxonomies',
2390 label: (0,external_wp_i18n_namespaceObject.__)('Taxonomy')
2391 }, {
2392 name: 'sidebar',
2393 kind: 'root',
2394 baseURL: '/wp/v2/sidebars',
2395 baseURLParams: {
2396 context: 'edit'
2397 },
2398 plural: 'sidebars',
2399 transientEdits: {
2400 blocks: true
2401 },
2402 label: (0,external_wp_i18n_namespaceObject.__)('Widget areas')
2403 }, {
2404 name: 'widget',
2405 kind: 'root',
2406 baseURL: '/wp/v2/widgets',
2407 baseURLParams: {
2408 context: 'edit'
2409 },
2410 plural: 'widgets',
2411 transientEdits: {
2412 blocks: true
2413 },
2414 label: (0,external_wp_i18n_namespaceObject.__)('Widgets')
2415 }, {
2416 name: 'widgetType',
2417 kind: 'root',
2418 baseURL: '/wp/v2/widget-types',
2419 baseURLParams: {
2420 context: 'edit'
2421 },
2422 plural: 'widgetTypes',
2423 label: (0,external_wp_i18n_namespaceObject.__)('Widget types')
2424 }, {
2425 label: (0,external_wp_i18n_namespaceObject.__)('User'),
2426 name: 'user',
2427 kind: 'root',
2428 baseURL: '/wp/v2/users',
2429 baseURLParams: {
2430 context: 'edit'
2431 },
2432 plural: 'users'
2433 }, {
2434 name: 'comment',
2435 kind: 'root',
2436 baseURL: '/wp/v2/comments',
2437 baseURLParams: {
2438 context: 'edit'
2439 },
2440 plural: 'comments',
2441 label: (0,external_wp_i18n_namespaceObject.__)('Comment')
2442 }, {
2443 name: 'menu',
2444 kind: 'root',
2445 baseURL: '/wp/v2/menus',
2446 baseURLParams: {
2447 context: 'edit'
2448 },
2449 plural: 'menus',
2450 label: (0,external_wp_i18n_namespaceObject.__)('Menu')
2451 }, {
2452 name: 'menuItem',
2453 kind: 'root',
2454 baseURL: '/wp/v2/menu-items',
2455 baseURLParams: {
2456 context: 'edit'
2457 },
2458 plural: 'menuItems',
2459 label: (0,external_wp_i18n_namespaceObject.__)('Menu Item'),
2460 rawAttributes: ['title']
2461 }, {
2462 name: 'menuLocation',
2463 kind: 'root',
2464 baseURL: '/wp/v2/menu-locations',
2465 baseURLParams: {
2466 context: 'edit'
2467 },
2468 plural: 'menuLocations',
2469 label: (0,external_wp_i18n_namespaceObject.__)('Menu Location'),
2470 key: 'name'
2471 }, {
2472 label: (0,external_wp_i18n_namespaceObject.__)('Global Styles'),
2473 name: 'globalStyles',
2474 kind: 'root',
2475 baseURL: '/wp/v2/global-styles',
2476 baseURLParams: {
2477 context: 'edit'
2478 },
2479 plural: 'globalStylesVariations',
2480 // Should be different than name.
2481 getTitle: record => record?.title?.rendered || record?.title
2482 }, {
2483 label: (0,external_wp_i18n_namespaceObject.__)('Themes'),
2484 name: 'theme',
2485 kind: 'root',
2486 baseURL: '/wp/v2/themes',
2487 baseURLParams: {
2488 context: 'edit'
2489 },
2490 key: 'stylesheet'
2491 }, {
2492 label: (0,external_wp_i18n_namespaceObject.__)('Plugins'),
2493 name: 'plugin',
2494 kind: 'root',
2495 baseURL: '/wp/v2/plugins',
2496 baseURLParams: {
2497 context: 'edit'
2498 },
2499 key: 'plugin'
2500 }];
2501 const additionalEntityConfigLoaders = [{
2502 kind: 'postType',
2503 loadEntities: loadPostTypeEntities
2504 }, {
2505 kind: 'taxonomy',
2506 loadEntities: loadTaxonomyEntities
2507 }];
2508 /**
2509 * Returns a function to be used to retrieve extra edits to apply before persisting a post type.
2510 *
2511 * @param {Object} persistedRecord Already persisted Post
2512 * @param {Object} edits Edits.
2513 * @return {Object} Updated edits.
2514 */
2515
2516 const prePersistPostType = (persistedRecord, edits) => {
2517 const newEdits = {};
2518
2519 if (persistedRecord?.status === 'auto-draft') {
2520 // Saving an auto-draft should create a draft by default.
2521 if (!edits.status && !newEdits.status) {
2522 newEdits.status = 'draft';
2523 } // Fix the auto-draft default title.
2524
2525
2526 if ((!edits.title || edits.title === 'Auto Draft') && !newEdits.title && (!persistedRecord?.title || persistedRecord?.title === 'Auto Draft')) {
2527 newEdits.title = '';
2528 }
2529 }
2530
2531 return newEdits;
2532 };
2533 /**
2534 * Returns the list of post type entities.
2535 *
2536 * @return {Promise} Entities promise
2537 */
2538
2539 async function loadPostTypeEntities() {
2540 const postTypes = await external_wp_apiFetch_default()({
2541 path: '/wp/v2/types?context=view'
2542 });
2543 return Object.entries(postTypes !== null && postTypes !== void 0 ? postTypes : {}).map(([name, postType]) => {
2544 var _postType$rest_namesp;
2545
2546 const isTemplate = ['wp_template', 'wp_template_part'].includes(name);
2547 const namespace = (_postType$rest_namesp = postType?.rest_namespace) !== null && _postType$rest_namesp !== void 0 ? _postType$rest_namesp : 'wp/v2';
2548 return {
2549 kind: 'postType',
2550 baseURL: `/${namespace}/${postType.rest_base}`,
2551 baseURLParams: {
2552 context: 'edit'
2553 },
2554 name,
2555 label: postType.name,
2556 transientEdits: {
2557 blocks: true,
2558 selection: true
2559 },
2560 mergedEdits: {
2561 meta: true
2562 },
2563 rawAttributes: POST_RAW_ATTRIBUTES,
2564 getTitle: record => {
2565 var _record$slug;
2566
2567 return record?.title?.rendered || record?.title || (isTemplate ? capitalCase((_record$slug = record.slug) !== null && _record$slug !== void 0 ? _record$slug : '') : String(record.id));
2568 },
2569 __unstablePrePersist: isTemplate ? undefined : prePersistPostType,
2570 __unstable_rest_base: postType.rest_base
2571 };
2572 });
2573 }
2574 /**
2575 * Returns the list of the taxonomies entities.
2576 *
2577 * @return {Promise} Entities promise
2578 */
2579
2580
2581 async function loadTaxonomyEntities() {
2582 const taxonomies = await external_wp_apiFetch_default()({
2583 path: '/wp/v2/taxonomies?context=view'
2584 });
2585 return Object.entries(taxonomies !== null && taxonomies !== void 0 ? taxonomies : {}).map(([name, taxonomy]) => {
2586 var _taxonomy$rest_namesp;
2587
2588 const namespace = (_taxonomy$rest_namesp = taxonomy?.rest_namespace) !== null && _taxonomy$rest_namesp !== void 0 ? _taxonomy$rest_namesp : 'wp/v2';
2589 return {
2590 kind: 'taxonomy',
2591 baseURL: `/${namespace}/${taxonomy.rest_base}`,
2592 baseURLParams: {
2593 context: 'edit'
2594 },
2595 name,
2596 label: taxonomy.name
2597 };
2598 });
2599 }
2600 /**
2601 * Returns the entity's getter method name given its kind and name.
2602 *
2603 * @example
2604 * ```js
2605 * const nameSingular = getMethodName( 'root', 'theme', 'get' );
2606 * // nameSingular is getRootTheme
2607 *
2608 * const namePlural = getMethodName( 'root', 'theme', 'set' );
2609 * // namePlural is setRootThemes
2610 * ```
2611 *
2612 * @param {string} kind Entity kind.
2613 * @param {string} name Entity name.
2614 * @param {string} prefix Function prefix.
2615 * @param {boolean} usePlural Whether to use the plural form or not.
2616 *
2617 * @return {string} Method name
2618 */
2619
2620
2621 const getMethodName = (kind, name, prefix = 'get', usePlural = false) => {
2622 const entityConfig = rootEntitiesConfig.find(config => config.kind === kind && config.name === name);
2623 const kindPrefix = kind === 'root' ? '' : pascalCase(kind);
2624 const nameSuffix = pascalCase(name) + (usePlural ? 's' : '');
2625 const suffix = usePlural && 'plural' in entityConfig && entityConfig?.plural ? pascalCase(entityConfig.plural) : nameSuffix;
2626 return `${prefix}${kindPrefix}${suffix}`;
2627 };
2628 /**
2629 * Loads the kind entities into the store.
2630 *
2631 * @param {string} kind Kind
2632 *
2633 * @return {(thunkArgs: object) => Promise<Array>} Entities
2634 */
2635
2636 const getOrLoadEntitiesConfig = kind => async ({
2637 select,
2638 dispatch
2639 }) => {
2640 let configs = select.getEntitiesConfig(kind);
2641
2642 if (configs && configs.length !== 0) {
2643 return configs;
2644 }
2645
2646 const loader = additionalEntityConfigLoaders.find(l => l.kind === kind);
2647
2648 if (!loader) {
2649 return [];
2650 }
2651
2652 configs = await loader.loadEntities();
2653 dispatch(addEntities(configs));
2654 return configs;
2655 };
2656
2657 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/get-normalized-comma-separable.js
2658 /**
2659 * Given a value which can be specified as one or the other of a comma-separated
2660 * string or an array, returns a value normalized to an array of strings, or
2661 * null if the value cannot be interpreted as either.
2662 *
2663 * @param {string|string[]|*} value
2664 *
2665 * @return {?(string[])} Normalized field value.
2666 */
2667 function getNormalizedCommaSeparable(value) {
2668 if (typeof value === 'string') {
2669 return value.split(',');
2670 } else if (Array.isArray(value)) {
2671 return value;
2672 }
2673
2674 return null;
2675 }
2676
2677 /* harmony default export */ const get_normalized_comma_separable = (getNormalizedCommaSeparable);
2678
2679 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/with-weak-map-cache.js
2680 /**
2681 * Given a function, returns an enhanced function which caches the result and
2682 * tracks in WeakMap. The result is only cached if the original function is
2683 * passed a valid object-like argument (requirement for WeakMap key).
2684 *
2685 * @param {Function} fn Original function.
2686 *
2687 * @return {Function} Enhanced caching function.
2688 */
2689 function withWeakMapCache(fn) {
2690 const cache = new WeakMap();
2691 return key => {
2692 let value;
2693
2694 if (cache.has(key)) {
2695 value = cache.get(key);
2696 } else {
2697 value = fn(key); // Can reach here if key is not valid for WeakMap, since `has`
2698 // will return false for invalid key. Since `set` will throw,
2699 // ensure that key is valid before setting into cache.
2700
2701 if (key !== null && typeof key === 'object') {
2702 cache.set(key, value);
2703 }
2704 }
2705
2706 return value;
2707 };
2708 }
2709
2710 /* harmony default export */ const with_weak_map_cache = (withWeakMapCache);
2711
2712 ;// CONCATENATED MODULE: ./packages/core-data/build-module/queried-data/get-query-parts.js
2713 /**
2714 * WordPress dependencies
2715 */
2716
2717 /**
2718 * Internal dependencies
2719 */
2720
2721
2722 /**
2723 * An object of properties describing a specific query.
2724 *
2725 * @typedef {Object} WPQueriedDataQueryParts
2726 *
2727 * @property {number} page The query page (1-based index, default 1).
2728 * @property {number} perPage Items per page for query (default 10).
2729 * @property {string} stableKey An encoded stable string of all non-
2730 * pagination, non-fields query parameters.
2731 * @property {?(string[])} fields Target subset of fields to derive from
2732 * item objects.
2733 * @property {?(number[])} include Specific item IDs to include.
2734 * @property {string} context Scope under which the request is made;
2735 * determines returned fields in response.
2736 */
2737
2738 /**
2739 * Given a query object, returns an object of parts, including pagination
2740 * details (`page` and `perPage`, or default values). All other properties are
2741 * encoded into a stable (idempotent) `stableKey` value.
2742 *
2743 * @param {Object} query Optional query object.
2744 *
2745 * @return {WPQueriedDataQueryParts} Query parts.
2746 */
2747
2748 function getQueryParts(query) {
2749 /**
2750 * @type {WPQueriedDataQueryParts}
2751 */
2752 const parts = {
2753 stableKey: '',
2754 page: 1,
2755 perPage: 10,
2756 fields: null,
2757 include: null,
2758 context: 'default'
2759 }; // Ensure stable key by sorting keys. Also more efficient for iterating.
2760
2761 const keys = Object.keys(query).sort();
2762
2763 for (let i = 0; i < keys.length; i++) {
2764 const key = keys[i];
2765 let value = query[key];
2766
2767 switch (key) {
2768 case 'page':
2769 parts[key] = Number(value);
2770 break;
2771
2772 case 'per_page':
2773 parts.perPage = Number(value);
2774 break;
2775
2776 case 'context':
2777 parts.context = value;
2778 break;
2779
2780 default:
2781 // While in theory, we could exclude "_fields" from the stableKey
2782 // because two request with different fields have the same results
2783 // We're not able to ensure that because the server can decide to omit
2784 // fields from the response even if we explicitly asked for it.
2785 // Example: Asking for titles in posts without title support.
2786 if (key === '_fields') {
2787 var _getNormalizedCommaSe;
2788
2789 parts.fields = (_getNormalizedCommaSe = get_normalized_comma_separable(value)) !== null && _getNormalizedCommaSe !== void 0 ? _getNormalizedCommaSe : []; // Make sure to normalize value for `stableKey`
2790
2791 value = parts.fields.join();
2792 } // Two requests with different include values cannot have same results.
2793
2794
2795 if (key === 'include') {
2796 var _getNormalizedCommaSe2;
2797
2798 if (typeof value === 'number') {
2799 value = value.toString();
2800 }
2801
2802 parts.include = ((_getNormalizedCommaSe2 = get_normalized_comma_separable(value)) !== null && _getNormalizedCommaSe2 !== void 0 ? _getNormalizedCommaSe2 : []).map(Number); // Normalize value for `stableKey`.
2803
2804 value = parts.include.join();
2805 } // While it could be any deterministic string, for simplicity's
2806 // sake mimic querystring encoding for stable key.
2807 //
2808 // TODO: For consistency with PHP implementation, addQueryArgs
2809 // should accept a key value pair, which may optimize its
2810 // implementation for our use here, vs. iterating an object
2811 // with only a single key.
2812
2813
2814 parts.stableKey += (parts.stableKey ? '&' : '') + (0,external_wp_url_namespaceObject.addQueryArgs)('', {
2815 [key]: value
2816 }).slice(1);
2817 }
2818 }
2819
2820 return parts;
2821 }
2822 /* harmony default export */ const get_query_parts = (with_weak_map_cache(getQueryParts));
2823
2824 ;// CONCATENATED MODULE: ./packages/core-data/build-module/queried-data/reducer.js
2825 /**
2826 * WordPress dependencies
2827 */
2828
2829
2830 /**
2831 * Internal dependencies
2832 */
2833
2834
2835
2836
2837
2838 function getContextFromAction(action) {
2839 const {
2840 query
2841 } = action;
2842
2843 if (!query) {
2844 return 'default';
2845 }
2846
2847 const queryParts = get_query_parts(query);
2848 return queryParts.context;
2849 }
2850 /**
2851 * Returns a merged array of item IDs, given details of the received paginated
2852 * items. The array is sparse-like with `undefined` entries where holes exist.
2853 *
2854 * @param {?Array<number>} itemIds Original item IDs (default empty array).
2855 * @param {number[]} nextItemIds Item IDs to merge.
2856 * @param {number} page Page of items merged.
2857 * @param {number} perPage Number of items per page.
2858 *
2859 * @return {number[]} Merged array of item IDs.
2860 */
2861
2862
2863 function getMergedItemIds(itemIds, nextItemIds, page, perPage) {
2864 var _itemIds$length;
2865
2866 const receivedAllIds = page === 1 && perPage === -1;
2867
2868 if (receivedAllIds) {
2869 return nextItemIds;
2870 }
2871
2872 const nextItemIdsStartIndex = (page - 1) * perPage; // If later page has already been received, default to the larger known
2873 // size of the existing array, else calculate as extending the existing.
2874
2875 const size = Math.max((_itemIds$length = itemIds?.length) !== null && _itemIds$length !== void 0 ? _itemIds$length : 0, nextItemIdsStartIndex + nextItemIds.length); // Preallocate array since size is known.
2876
2877 const mergedItemIds = new Array(size);
2878
2879 for (let i = 0; i < size; i++) {
2880 // Preserve existing item ID except for subset of range of next items.
2881 const isInNextItemsRange = i >= nextItemIdsStartIndex && i < nextItemIdsStartIndex + nextItemIds.length;
2882 mergedItemIds[i] = isInNextItemsRange ? nextItemIds[i - nextItemIdsStartIndex] : itemIds?.[i];
2883 }
2884
2885 return mergedItemIds;
2886 }
2887 /**
2888 * Helper function to filter out entities with certain IDs.
2889 * Entities are keyed by their ID.
2890 *
2891 * @param {Object} entities Entity objects, keyed by entity ID.
2892 * @param {Array} ids Entity IDs to filter out.
2893 *
2894 * @return {Object} Filtered entities.
2895 */
2896
2897 function removeEntitiesById(entities, ids) {
2898 return Object.fromEntries(Object.entries(entities).filter(([id]) => !ids.some(itemId => {
2899 if (Number.isInteger(itemId)) {
2900 return itemId === +id;
2901 }
2902
2903 return itemId === id;
2904 })));
2905 }
2906 /**
2907 * Reducer tracking items state, keyed by ID. Items are assumed to be normal,
2908 * where identifiers are common across all queries.
2909 *
2910 * @param {Object} state Current state.
2911 * @param {Object} action Dispatched action.
2912 *
2913 * @return {Object} Next state.
2914 */
2915
2916
2917 function items(state = {}, action) {
2918 switch (action.type) {
2919 case 'RECEIVE_ITEMS':
2920 {
2921 const context = getContextFromAction(action);
2922 const key = action.key || DEFAULT_ENTITY_KEY;
2923 return { ...state,
2924 [context]: { ...state[context],
2925 ...action.items.reduce((accumulator, value) => {
2926 const itemId = value[key];
2927 accumulator[itemId] = conservativeMapItem(state?.[context]?.[itemId], value);
2928 return accumulator;
2929 }, {})
2930 }
2931 };
2932 }
2933
2934 case 'REMOVE_ITEMS':
2935 return Object.fromEntries(Object.entries(state).map(([itemId, contextState]) => [itemId, removeEntitiesById(contextState, action.itemIds)]));
2936 }
2937
2938 return state;
2939 }
2940 /**
2941 * Reducer tracking item completeness, keyed by ID. A complete item is one for
2942 * which all fields are known. This is used in supporting `_fields` queries,
2943 * where not all properties associated with an entity are necessarily returned.
2944 * In such cases, completeness is used as an indication of whether it would be
2945 * safe to use queried data for a non-`_fields`-limited request.
2946 *
2947 * @param {Object<string,Object<string,boolean>>} state Current state.
2948 * @param {Object} action Dispatched action.
2949 *
2950 * @return {Object<string,Object<string,boolean>>} Next state.
2951 */
2952
2953 function itemIsComplete(state = {}, action) {
2954 switch (action.type) {
2955 case 'RECEIVE_ITEMS':
2956 {
2957 const context = getContextFromAction(action);
2958 const {
2959 query,
2960 key = DEFAULT_ENTITY_KEY
2961 } = action; // An item is considered complete if it is received without an associated
2962 // fields query. Ideally, this would be implemented in such a way where the
2963 // complete aggregate of all fields would satisfy completeness. Since the
2964 // fields are not consistent across all entities, this would require
2965 // introspection on the REST schema for each entity to know which fields
2966 // compose a complete item for that entity.
2967
2968 const queryParts = query ? get_query_parts(query) : {};
2969 const isCompleteQuery = !query || !Array.isArray(queryParts.fields);
2970 return { ...state,
2971 [context]: { ...state[context],
2972 ...action.items.reduce((result, item) => {
2973 const itemId = item[key]; // Defer to completeness if already assigned. Technically the
2974 // data may be outdated if receiving items for a field subset.
2975
2976 result[itemId] = state?.[context]?.[itemId] || isCompleteQuery;
2977 return result;
2978 }, {})
2979 }
2980 };
2981 }
2982
2983 case 'REMOVE_ITEMS':
2984 return Object.fromEntries(Object.entries(state).map(([itemId, contextState]) => [itemId, removeEntitiesById(contextState, action.itemIds)]));
2985 }
2986
2987 return state;
2988 }
2989 /**
2990 * Reducer tracking queries state, keyed by stable query key. Each reducer
2991 * query object includes `itemIds` and `requestingPageByPerPage`.
2992 *
2993 * @param {Object} state Current state.
2994 * @param {Object} action Dispatched action.
2995 *
2996 * @return {Object} Next state.
2997 */
2998
2999 const receiveQueries = (0,external_wp_compose_namespaceObject.compose)([// Limit to matching action type so we don't attempt to replace action on
3000 // an unhandled action.
3001 if_matching_action(action => 'query' in action), // Inject query parts into action for use both in `onSubKey` and reducer.
3002 replace_action(action => {
3003 // `ifMatchingAction` still passes on initialization, where state is
3004 // undefined and a query is not assigned. Avoid attempting to parse
3005 // parts. `onSubKey` will omit by lack of `stableKey`.
3006 if (action.query) {
3007 return { ...action,
3008 ...get_query_parts(action.query)
3009 };
3010 }
3011
3012 return action;
3013 }), on_sub_key('context'), // Queries shape is shared, but keyed by query `stableKey` part. Original
3014 // reducer tracks only a single query object.
3015 on_sub_key('stableKey')])((state = null, action) => {
3016 const {
3017 type,
3018 page,
3019 perPage,
3020 key = DEFAULT_ENTITY_KEY
3021 } = action;
3022
3023 if (type !== 'RECEIVE_ITEMS') {
3024 return state;
3025 }
3026
3027 return getMergedItemIds(state || [], action.items.map(item => item[key]), page, perPage);
3028 });
3029 /**
3030 * Reducer tracking queries state.
3031 *
3032 * @param {Object} state Current state.
3033 * @param {Object} action Dispatched action.
3034 *
3035 * @return {Object} Next state.
3036 */
3037
3038 const queries = (state = {}, action) => {
3039 switch (action.type) {
3040 case 'RECEIVE_ITEMS':
3041 return receiveQueries(state, action);
3042
3043 case 'REMOVE_ITEMS':
3044 const removedItems = action.itemIds.reduce((result, itemId) => {
3045 result[itemId] = true;
3046 return result;
3047 }, {});
3048 return Object.fromEntries(Object.entries(state).map(([queryGroup, contextQueries]) => [queryGroup, Object.fromEntries(Object.entries(contextQueries).map(([query, queryItems]) => [query, queryItems.filter(queryId => !removedItems[queryId])]))]));
3049
3050 default:
3051 return state;
3052 }
3053 };
3054
3055 /* harmony default export */ const reducer = ((0,external_wp_data_namespaceObject.combineReducers)({
3056 items,
3057 itemIsComplete,
3058 queries
3059 }));
3060
3061 ;// CONCATENATED MODULE: ./packages/core-data/build-module/reducer.js
3062 /**
3063 * External dependencies
3064 */
3065
3066 /**
3067 * WordPress dependencies
3068 */
3069
3070
3071
3072
3073 /**
3074 * Internal dependencies
3075 */
3076
3077
3078
3079
3080 /** @typedef {import('./types').AnyFunction} AnyFunction */
3081
3082 /**
3083 * Reducer managing terms state. Keyed by taxonomy slug, the value is either
3084 * undefined (if no request has been made for given taxonomy), null (if a
3085 * request is in-flight for given taxonomy), or the array of terms for the
3086 * taxonomy.
3087 *
3088 * @param {Object} state Current state.
3089 * @param {Object} action Dispatched action.
3090 *
3091 * @return {Object} Updated state.
3092 */
3093
3094 function terms(state = {}, action) {
3095 switch (action.type) {
3096 case 'RECEIVE_TERMS':
3097 return { ...state,
3098 [action.taxonomy]: action.terms
3099 };
3100 }
3101
3102 return state;
3103 }
3104 /**
3105 * Reducer managing authors state. Keyed by id.
3106 *
3107 * @param {Object} state Current state.
3108 * @param {Object} action Dispatched action.
3109 *
3110 * @return {Object} Updated state.
3111 */
3112
3113 function users(state = {
3114 byId: {},
3115 queries: {}
3116 }, action) {
3117 switch (action.type) {
3118 case 'RECEIVE_USER_QUERY':
3119 return {
3120 byId: { ...state.byId,
3121 // Key users by their ID.
3122 ...action.users.reduce((newUsers, user) => ({ ...newUsers,
3123 [user.id]: user
3124 }), {})
3125 },
3126 queries: { ...state.queries,
3127 [action.queryID]: action.users.map(user => user.id)
3128 }
3129 };
3130 }
3131
3132 return state;
3133 }
3134 /**
3135 * Reducer managing current user state.
3136 *
3137 * @param {Object} state Current state.
3138 * @param {Object} action Dispatched action.
3139 *
3140 * @return {Object} Updated state.
3141 */
3142
3143 function currentUser(state = {}, action) {
3144 switch (action.type) {
3145 case 'RECEIVE_CURRENT_USER':
3146 return action.currentUser;
3147 }
3148
3149 return state;
3150 }
3151 /**
3152 * Reducer managing taxonomies.
3153 *
3154 * @param {Object} state Current state.
3155 * @param {Object} action Dispatched action.
3156 *
3157 * @return {Object} Updated state.
3158 */
3159
3160 function taxonomies(state = [], action) {
3161 switch (action.type) {
3162 case 'RECEIVE_TAXONOMIES':
3163 return action.taxonomies;
3164 }
3165
3166 return state;
3167 }
3168 /**
3169 * Reducer managing the current theme.
3170 *
3171 * @param {string|undefined} state Current state.
3172 * @param {Object} action Dispatched action.
3173 *
3174 * @return {string|undefined} Updated state.
3175 */
3176
3177 function currentTheme(state = undefined, action) {
3178 switch (action.type) {
3179 case 'RECEIVE_CURRENT_THEME':
3180 return action.currentTheme.stylesheet;
3181 }
3182
3183 return state;
3184 }
3185 /**
3186 * Reducer managing the current global styles id.
3187 *
3188 * @param {string|undefined} state Current state.
3189 * @param {Object} action Dispatched action.
3190 *
3191 * @return {string|undefined} Updated state.
3192 */
3193
3194 function currentGlobalStylesId(state = undefined, action) {
3195 switch (action.type) {
3196 case 'RECEIVE_CURRENT_GLOBAL_STYLES_ID':
3197 return action.id;
3198 }
3199
3200 return state;
3201 }
3202 /**
3203 * Reducer managing the theme base global styles.
3204 *
3205 * @param {Record<string, object>} state Current state.
3206 * @param {Object} action Dispatched action.
3207 *
3208 * @return {Record<string, object>} Updated state.
3209 */
3210
3211 function themeBaseGlobalStyles(state = {}, action) {
3212 switch (action.type) {
3213 case 'RECEIVE_THEME_GLOBAL_STYLES':
3214 return { ...state,
3215 [action.stylesheet]: action.globalStyles
3216 };
3217 }
3218
3219 return state;
3220 }
3221 /**
3222 * Reducer managing the theme global styles variations.
3223 *
3224 * @param {Record<string, object>} state Current state.
3225 * @param {Object} action Dispatched action.
3226 *
3227 * @return {Record<string, object>} Updated state.
3228 */
3229
3230 function themeGlobalStyleVariations(state = {}, action) {
3231 switch (action.type) {
3232 case 'RECEIVE_THEME_GLOBAL_STYLE_VARIATIONS':
3233 return { ...state,
3234 [action.stylesheet]: action.variations
3235 };
3236 }
3237
3238 return state;
3239 }
3240
3241 const withMultiEntityRecordEdits = reducer => (state, action) => {
3242 if (action.type === 'UNDO' || action.type === 'REDO') {
3243 const {
3244 stackedEdits
3245 } = action;
3246 let newState = state;
3247 stackedEdits.forEach(({
3248 kind,
3249 name,
3250 recordId,
3251 property,
3252 from,
3253 to
3254 }) => {
3255 newState = reducer(newState, {
3256 type: 'EDIT_ENTITY_RECORD',
3257 kind,
3258 name,
3259 recordId,
3260 edits: {
3261 [property]: action.type === 'UNDO' ? from : to
3262 }
3263 });
3264 });
3265 return newState;
3266 }
3267
3268 return reducer(state, action);
3269 };
3270 /**
3271 * Higher Order Reducer for a given entity config. It supports:
3272 *
3273 * - Fetching
3274 * - Editing
3275 * - Saving
3276 *
3277 * @param {Object} entityConfig Entity config.
3278 *
3279 * @return {AnyFunction} Reducer.
3280 */
3281
3282
3283 function entity(entityConfig) {
3284 return (0,external_wp_compose_namespaceObject.compose)([withMultiEntityRecordEdits, // Limit to matching action type so we don't attempt to replace action on
3285 // an unhandled action.
3286 if_matching_action(action => action.name && action.kind && action.name === entityConfig.name && action.kind === entityConfig.kind), // Inject the entity config into the action.
3287 replace_action(action => {
3288 return { ...action,
3289 key: entityConfig.key || DEFAULT_ENTITY_KEY
3290 };
3291 })])((0,external_wp_data_namespaceObject.combineReducers)({
3292 queriedData: reducer,
3293 edits: (state = {}, action) => {
3294 var _action$query$context;
3295
3296 switch (action.type) {
3297 case 'RECEIVE_ITEMS':
3298 const context = (_action$query$context = action?.query?.context) !== null && _action$query$context !== void 0 ? _action$query$context : 'default';
3299
3300 if (context !== 'default') {
3301 return state;
3302 }
3303
3304 const nextState = { ...state
3305 };
3306
3307 for (const record of action.items) {
3308 const recordId = record[action.key];
3309 const edits = nextState[recordId];
3310
3311 if (!edits) {
3312 continue;
3313 }
3314
3315 const nextEdits = Object.keys(edits).reduce((acc, key) => {
3316 var _record$key$raw;
3317
3318 // If the edited value is still different to the persisted value,
3319 // keep the edited value in edits.
3320 if ( // Edits are the "raw" attribute values, but records may have
3321 // objects with more properties, so we use `get` here for the
3322 // comparison.
3323 !es6_default()(edits[key], (_record$key$raw = record[key]?.raw) !== null && _record$key$raw !== void 0 ? _record$key$raw : record[key]) && ( // Sometimes the server alters the sent value which means
3324 // we need to also remove the edits before the api request.
3325 !action.persistedEdits || !es6_default()(edits[key], action.persistedEdits[key]))) {
3326 acc[key] = edits[key];
3327 }
3328
3329 return acc;
3330 }, {});
3331
3332 if (Object.keys(nextEdits).length) {
3333 nextState[recordId] = nextEdits;
3334 } else {
3335 delete nextState[recordId];
3336 }
3337 }
3338
3339 return nextState;
3340
3341 case 'EDIT_ENTITY_RECORD':
3342 const nextEdits = { ...state[action.recordId],
3343 ...action.edits
3344 };
3345 Object.keys(nextEdits).forEach(key => {
3346 // Delete cleared edits so that the properties
3347 // are not considered dirty.
3348 if (nextEdits[key] === undefined) {
3349 delete nextEdits[key];
3350 }
3351 });
3352 return { ...state,
3353 [action.recordId]: nextEdits
3354 };
3355 }
3356
3357 return state;
3358 },
3359 saving: (state = {}, action) => {
3360 switch (action.type) {
3361 case 'SAVE_ENTITY_RECORD_START':
3362 case 'SAVE_ENTITY_RECORD_FINISH':
3363 return { ...state,
3364 [action.recordId]: {
3365 pending: action.type === 'SAVE_ENTITY_RECORD_START',
3366 error: action.error,
3367 isAutosave: action.isAutosave
3368 }
3369 };
3370 }
3371
3372 return state;
3373 },
3374 deleting: (state = {}, action) => {
3375 switch (action.type) {
3376 case 'DELETE_ENTITY_RECORD_START':
3377 case 'DELETE_ENTITY_RECORD_FINISH':
3378 return { ...state,
3379 [action.recordId]: {
3380 pending: action.type === 'DELETE_ENTITY_RECORD_START',
3381 error: action.error
3382 }
3383 };
3384 }
3385
3386 return state;
3387 }
3388 }));
3389 }
3390 /**
3391 * Reducer keeping track of the registered entities.
3392 *
3393 * @param {Object} state Current state.
3394 * @param {Object} action Dispatched action.
3395 *
3396 * @return {Object} Updated state.
3397 */
3398
3399
3400 function entitiesConfig(state = rootEntitiesConfig, action) {
3401 switch (action.type) {
3402 case 'ADD_ENTITIES':
3403 return [...state, ...action.entities];
3404 }
3405
3406 return state;
3407 }
3408 /**
3409 * Reducer keeping track of the registered entities config and data.
3410 *
3411 * @param {Object} state Current state.
3412 * @param {Object} action Dispatched action.
3413 *
3414 * @return {Object} Updated state.
3415 */
3416
3417 const entities = (state = {}, action) => {
3418 const newConfig = entitiesConfig(state.config, action); // Generates a dynamic reducer for the entities.
3419
3420 let entitiesDataReducer = state.reducer;
3421
3422 if (!entitiesDataReducer || newConfig !== state.config) {
3423 const entitiesByKind = newConfig.reduce((acc, record) => {
3424 const {
3425 kind
3426 } = record;
3427
3428 if (!acc[kind]) {
3429 acc[kind] = [];
3430 }
3431
3432 acc[kind].push(record);
3433 return acc;
3434 }, {});
3435 entitiesDataReducer = (0,external_wp_data_namespaceObject.combineReducers)(Object.entries(entitiesByKind).reduce((memo, [kind, subEntities]) => {
3436 const kindReducer = (0,external_wp_data_namespaceObject.combineReducers)(subEntities.reduce((kindMemo, entityConfig) => ({ ...kindMemo,
3437 [entityConfig.name]: entity(entityConfig)
3438 }), {}));
3439 memo[kind] = kindReducer;
3440 return memo;
3441 }, {}));
3442 }
3443
3444 const newData = entitiesDataReducer(state.records, action);
3445
3446 if (newData === state.records && newConfig === state.config && entitiesDataReducer === state.reducer) {
3447 return state;
3448 }
3449
3450 return {
3451 reducer: entitiesDataReducer,
3452 records: newData,
3453 config: newConfig
3454 };
3455 };
3456 /**
3457 * @typedef {Object} UndoStateMeta
3458 *
3459 * @property {number} list The undo stack.
3460 * @property {number} offset Where in the undo stack we are.
3461 * @property {Object} cache Cache of unpersisted edits.
3462 */
3463
3464 /** @typedef {Array<Object> & UndoStateMeta} UndoState */
3465
3466 /**
3467 * @type {UndoState}
3468 *
3469 * @todo Given how we use this we might want to make a custom class for it.
3470 */
3471
3472 const UNDO_INITIAL_STATE = {
3473 list: [],
3474 offset: 0
3475 };
3476 /**
3477 * Reducer keeping track of entity edit undo history.
3478 *
3479 * @param {UndoState} state Current state.
3480 * @param {Object} action Dispatched action.
3481 *
3482 * @return {UndoState} Updated state.
3483 */
3484
3485 function reducer_undo(state = UNDO_INITIAL_STATE, action) {
3486 const omitPendingRedos = currentState => {
3487 return { ...currentState,
3488 list: currentState.list.slice(0, currentState.offset || undefined),
3489 offset: 0
3490 };
3491 };
3492
3493 const appendCachedEditsToLastUndo = currentState => {
3494 if (!currentState.cache) {
3495 return currentState;
3496 }
3497
3498 let nextState = { ...currentState,
3499 list: [...currentState.list]
3500 };
3501 nextState = omitPendingRedos(nextState);
3502 const previousUndoState = nextState.list.pop();
3503 const updatedUndoState = currentState.cache.reduce(appendEditToStack, previousUndoState);
3504 nextState.list.push(updatedUndoState);
3505 return { ...nextState,
3506 cache: undefined
3507 };
3508 };
3509
3510 const appendEditToStack = (stack = [], {
3511 kind,
3512 name,
3513 recordId,
3514 property,
3515 from,
3516 to
3517 }) => {
3518 const existingEditIndex = stack?.findIndex(({
3519 kind: k,
3520 name: n,
3521 recordId: r,
3522 property: p
3523 }) => {
3524 return k === kind && n === name && r === recordId && p === property;
3525 });
3526 const nextStack = [...stack];
3527
3528 if (existingEditIndex !== -1) {
3529 // If the edit is already in the stack leave the initial "from" value.
3530 nextStack[existingEditIndex] = { ...nextStack[existingEditIndex],
3531 to
3532 };
3533 } else {
3534 nextStack.push({
3535 kind,
3536 name,
3537 recordId,
3538 property,
3539 from,
3540 to
3541 });
3542 }
3543
3544 return nextStack;
3545 };
3546
3547 switch (action.type) {
3548 case 'CREATE_UNDO_LEVEL':
3549 return appendCachedEditsToLastUndo(state);
3550
3551 case 'UNDO':
3552 case 'REDO':
3553 {
3554 const nextState = appendCachedEditsToLastUndo(state);
3555 return { ...nextState,
3556 offset: state.offset + (action.type === 'UNDO' ? -1 : 1)
3557 };
3558 }
3559
3560 case 'EDIT_ENTITY_RECORD':
3561 {
3562 if (!action.meta.undo) {
3563 return state;
3564 }
3565
3566 const edits = Object.keys(action.edits).map(key => {
3567 return {
3568 kind: action.kind,
3569 name: action.name,
3570 recordId: action.recordId,
3571 property: key,
3572 from: action.meta.undo.edits[key],
3573 to: action.edits[key]
3574 };
3575 });
3576
3577 if (action.meta.undo.isCached) {
3578 return { ...state,
3579 cache: edits.reduce(appendEditToStack, state.cache)
3580 };
3581 }
3582
3583 let nextState = omitPendingRedos(state);
3584 nextState = appendCachedEditsToLastUndo(nextState);
3585 nextState = { ...nextState,
3586 list: [...nextState.list]
3587 }; // When an edit is a function it's an optimization to avoid running some expensive operation.
3588 // We can't rely on the function references being the same so we opt out of comparing them here.
3589
3590 const comparisonUndoEdits = Object.values(action.meta.undo.edits).filter(edit => typeof edit !== 'function');
3591 const comparisonEdits = Object.values(action.edits).filter(edit => typeof edit !== 'function');
3592
3593 if (!external_wp_isShallowEqual_default()(comparisonUndoEdits, comparisonEdits)) {
3594 nextState.list.push(edits);
3595 }
3596
3597 return nextState;
3598 }
3599 }
3600
3601 return state;
3602 }
3603 /**
3604 * Reducer managing embed preview data.
3605 *
3606 * @param {Object} state Current state.
3607 * @param {Object} action Dispatched action.
3608 *
3609 * @return {Object} Updated state.
3610 */
3611
3612 function embedPreviews(state = {}, action) {
3613 switch (action.type) {
3614 case 'RECEIVE_EMBED_PREVIEW':
3615 const {
3616 url,
3617 preview
3618 } = action;
3619 return { ...state,
3620 [url]: preview
3621 };
3622 }
3623
3624 return state;
3625 }
3626 /**
3627 * State which tracks whether the user can perform an action on a REST
3628 * resource.
3629 *
3630 * @param {Object} state Current state.
3631 * @param {Object} action Dispatched action.
3632 *
3633 * @return {Object} Updated state.
3634 */
3635
3636 function userPermissions(state = {}, action) {
3637 switch (action.type) {
3638 case 'RECEIVE_USER_PERMISSION':
3639 return { ...state,
3640 [action.key]: action.isAllowed
3641 };
3642 }
3643
3644 return state;
3645 }
3646 /**
3647 * Reducer returning autosaves keyed by their parent's post id.
3648 *
3649 * @param {Object} state Current state.
3650 * @param {Object} action Dispatched action.
3651 *
3652 * @return {Object} Updated state.
3653 */
3654
3655 function autosaves(state = {}, action) {
3656 switch (action.type) {
3657 case 'RECEIVE_AUTOSAVES':
3658 const {
3659 postId,
3660 autosaves: autosavesData
3661 } = action;
3662 return { ...state,
3663 [postId]: autosavesData
3664 };
3665 }
3666
3667 return state;
3668 }
3669 function blockPatterns(state = [], action) {
3670 switch (action.type) {
3671 case 'RECEIVE_BLOCK_PATTERNS':
3672 return action.patterns;
3673 }
3674
3675 return state;
3676 }
3677 function blockPatternCategories(state = [], action) {
3678 switch (action.type) {
3679 case 'RECEIVE_BLOCK_PATTERN_CATEGORIES':
3680 return action.categories;
3681 }
3682
3683 return state;
3684 }
3685 function navigationFallbackId(state = null, action) {
3686 switch (action.type) {
3687 case 'RECEIVE_NAVIGATION_FALLBACK_ID':
3688 return action.fallbackId;
3689 }
3690
3691 return state;
3692 }
3693 /**
3694 * Reducer managing the theme global styles revisions.
3695 *
3696 * @param {Record<string, object>} state Current state.
3697 * @param {Object} action Dispatched action.
3698 *
3699 * @return {Record<string, object>} Updated state.
3700 */
3701
3702 function themeGlobalStyleRevisions(state = {}, action) {
3703 switch (action.type) {
3704 case 'RECEIVE_THEME_GLOBAL_STYLE_REVISIONS':
3705 return { ...state,
3706 [action.currentId]: action.revisions
3707 };
3708 }
3709
3710 return state;
3711 }
3712 /* harmony default export */ const build_module_reducer = ((0,external_wp_data_namespaceObject.combineReducers)({
3713 terms,
3714 users,
3715 currentTheme,
3716 currentGlobalStylesId,
3717 currentUser,
3718 themeGlobalStyleVariations,
3719 themeBaseGlobalStyles,
3720 themeGlobalStyleRevisions,
3721 taxonomies,
3722 entities,
3723 undo: reducer_undo,
3724 embedPreviews,
3725 userPermissions,
3726 autosaves,
3727 blockPatterns,
3728 blockPatternCategories,
3729 navigationFallbackId
3730 }));
3731
3732 ;// CONCATENATED MODULE: ./node_modules/rememo/rememo.js
3733
3734
3735 /** @typedef {(...args: any[]) => *[]} GetDependants */
3736
3737 /** @typedef {() => void} Clear */
3738
3739 /**
3740 * @typedef {{
3741 * getDependants: GetDependants,
3742 * clear: Clear
3743 * }} EnhancedSelector
3744 */
3745
3746 /**
3747 * Internal cache entry.
3748 *
3749 * @typedef CacheNode
3750 *
3751 * @property {?CacheNode|undefined} [prev] Previous node.
3752 * @property {?CacheNode|undefined} [next] Next node.
3753 * @property {*[]} args Function arguments for cache entry.
3754 * @property {*} val Function result.
3755 */
3756
3757 /**
3758 * @typedef Cache
3759 *
3760 * @property {Clear} clear Function to clear cache.
3761 * @property {boolean} [isUniqueByDependants] Whether dependants are valid in
3762 * considering cache uniqueness. A cache is unique if dependents are all arrays
3763 * or objects.
3764 * @property {CacheNode?} [head] Cache head.
3765 * @property {*[]} [lastDependants] Dependants from previous invocation.
3766 */
3767
3768 /**
3769 * Arbitrary value used as key for referencing cache object in WeakMap tree.
3770 *
3771 * @type {{}}
3772 */
3773 var LEAF_KEY = {};
3774
3775 /**
3776 * Returns the first argument as the sole entry in an array.
3777 *
3778 * @template T
3779 *
3780 * @param {T} value Value to return.
3781 *
3782 * @return {[T]} Value returned as entry in array.
3783 */
3784 function arrayOf(value) {
3785 return [value];
3786 }
3787
3788 /**
3789 * Returns true if the value passed is object-like, or false otherwise. A value
3790 * is object-like if it can support property assignment, e.g. object or array.
3791 *
3792 * @param {*} value Value to test.
3793 *
3794 * @return {boolean} Whether value is object-like.
3795 */
3796 function isObjectLike(value) {
3797 return !!value && 'object' === typeof value;
3798 }
3799
3800 /**
3801 * Creates and returns a new cache object.
3802 *
3803 * @return {Cache} Cache object.
3804 */
3805 function createCache() {
3806 /** @type {Cache} */
3807 var cache = {
3808 clear: function () {
3809 cache.head = null;
3810 },
3811 };
3812
3813 return cache;
3814 }
3815
3816 /**
3817 * Returns true if entries within the two arrays are strictly equal by
3818 * reference from a starting index.
3819 *
3820 * @param {*[]} a First array.
3821 * @param {*[]} b Second array.
3822 * @param {number} fromIndex Index from which to start comparison.
3823 *
3824 * @return {boolean} Whether arrays are shallowly equal.
3825 */
3826 function isShallowEqual(a, b, fromIndex) {
3827 var i;
3828
3829 if (a.length !== b.length) {
3830 return false;
3831 }
3832
3833 for (i = fromIndex; i < a.length; i++) {
3834 if (a[i] !== b[i]) {
3835 return false;
3836 }
3837 }
3838
3839 return true;
3840 }
3841
3842 /**
3843 * Returns a memoized selector function. The getDependants function argument is
3844 * called before the memoized selector and is expected to return an immutable
3845 * reference or array of references on which the selector depends for computing
3846 * its own return value. The memoize cache is preserved only as long as those
3847 * dependant references remain the same. If getDependants returns a different
3848 * reference(s), the cache is cleared and the selector value regenerated.
3849 *
3850 * @template {(...args: *[]) => *} S
3851 *
3852 * @param {S} selector Selector function.
3853 * @param {GetDependants=} getDependants Dependant getter returning an array of
3854 * references used in cache bust consideration.
3855 */
3856 /* harmony default export */ function rememo(selector, getDependants) {
3857 /** @type {WeakMap<*,*>} */
3858 var rootCache;
3859
3860 /** @type {GetDependants} */
3861 var normalizedGetDependants = getDependants ? getDependants : arrayOf;
3862
3863 /**
3864 * Returns the cache for a given dependants array. When possible, a WeakMap
3865 * will be used to create a unique cache for each set of dependants. This
3866 * is feasible due to the nature of WeakMap in allowing garbage collection
3867 * to occur on entries where the key object is no longer referenced. Since
3868 * WeakMap requires the key to be an object, this is only possible when the
3869 * dependant is object-like. The root cache is created as a hierarchy where
3870 * each top-level key is the first entry in a dependants set, the value a
3871 * WeakMap where each key is the next dependant, and so on. This continues
3872 * so long as the dependants are object-like. If no dependants are object-
3873 * like, then the cache is shared across all invocations.
3874 *
3875 * @see isObjectLike
3876 *
3877 * @param {*[]} dependants Selector dependants.
3878 *
3879 * @return {Cache} Cache object.
3880 */
3881 function getCache(dependants) {
3882 var caches = rootCache,
3883 isUniqueByDependants = true,
3884 i,
3885 dependant,
3886 map,
3887 cache;
3888
3889 for (i = 0; i < dependants.length; i++) {
3890 dependant = dependants[i];
3891
3892 // Can only compose WeakMap from object-like key.
3893 if (!isObjectLike(dependant)) {
3894 isUniqueByDependants = false;
3895 break;
3896 }
3897
3898 // Does current segment of cache already have a WeakMap?
3899 if (caches.has(dependant)) {
3900 // Traverse into nested WeakMap.
3901 caches = caches.get(dependant);
3902 } else {
3903 // Create, set, and traverse into a new one.
3904 map = new WeakMap();
3905 caches.set(dependant, map);
3906 caches = map;
3907 }
3908 }
3909
3910 // We use an arbitrary (but consistent) object as key for the last item
3911 // in the WeakMap to serve as our running cache.
3912 if (!caches.has(LEAF_KEY)) {
3913 cache = createCache();
3914 cache.isUniqueByDependants = isUniqueByDependants;
3915 caches.set(LEAF_KEY, cache);
3916 }
3917
3918 return caches.get(LEAF_KEY);
3919 }
3920
3921 /**
3922 * Resets root memoization cache.
3923 */
3924 function clear() {
3925 rootCache = new WeakMap();
3926 }
3927
3928 /* eslint-disable jsdoc/check-param-names */
3929 /**
3930 * The augmented selector call, considering first whether dependants have
3931 * changed before passing it to underlying memoize function.
3932 *
3933 * @param {*} source Source object for derivation.
3934 * @param {...*} extraArgs Additional arguments to pass to selector.
3935 *
3936 * @return {*} Selector result.
3937 */
3938 /* eslint-enable jsdoc/check-param-names */
3939 function callSelector(/* source, ...extraArgs */) {
3940 var len = arguments.length,
3941 cache,
3942 node,
3943 i,
3944 args,
3945 dependants;
3946
3947 // Create copy of arguments (avoid leaking deoptimization).
3948 args = new Array(len);
3949 for (i = 0; i < len; i++) {
3950 args[i] = arguments[i];
3951 }
3952
3953 dependants = normalizedGetDependants.apply(null, args);
3954 cache = getCache(dependants);
3955
3956 // If not guaranteed uniqueness by dependants (primitive type), shallow
3957 // compare against last dependants and, if references have changed,
3958 // destroy cache to recalculate result.
3959 if (!cache.isUniqueByDependants) {
3960 if (
3961 cache.lastDependants &&
3962 !isShallowEqual(dependants, cache.lastDependants, 0)
3963 ) {
3964 cache.clear();
3965 }
3966
3967 cache.lastDependants = dependants;
3968 }
3969
3970 node = cache.head;
3971 while (node) {
3972 // Check whether node arguments match arguments
3973 if (!isShallowEqual(node.args, args, 1)) {
3974 node = node.next;
3975 continue;
3976 }
3977
3978 // At this point we can assume we've found a match
3979
3980 // Surface matched node to head if not already
3981 if (node !== cache.head) {
3982 // Adjust siblings to point to each other.
3983 /** @type {CacheNode} */ (node.prev).next = node.next;
3984 if (node.next) {
3985 node.next.prev = node.prev;
3986 }
3987
3988 node.next = cache.head;
3989 node.prev = null;
3990 /** @type {CacheNode} */ (cache.head).prev = node;
3991 cache.head = node;
3992 }
3993
3994 // Return immediately
3995 return node.val;
3996 }
3997
3998 // No cached value found. Continue to insertion phase:
3999
4000 node = /** @type {CacheNode} */ ({
4001 // Generate the result from original function
4002 val: selector.apply(null, args),
4003 });
4004
4005 // Avoid including the source object in the cache.
4006 args[0] = null;
4007 node.args = args;
4008
4009 // Don't need to check whether node is already head, since it would
4010 // have been returned above already if it was
4011
4012 // Shift existing head down list
4013 if (cache.head) {
4014 cache.head.prev = node;
4015 node.next = cache.head;
4016 }
4017
4018 cache.head = node;
4019
4020 return node.val;
4021 }
4022
4023 callSelector.getDependants = normalizedGetDependants;
4024 callSelector.clear = clear;
4025 clear();
4026
4027 return /** @type {S & EnhancedSelector} */ (callSelector);
4028 }
4029
4030 // EXTERNAL MODULE: ./node_modules/equivalent-key-map/equivalent-key-map.js
4031 var equivalent_key_map = __webpack_require__(2167);
4032 var equivalent_key_map_default = /*#__PURE__*/__webpack_require__.n(equivalent_key_map);
4033 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/set-nested-value.js
4034 /**
4035 * Sets the value at path of object.
4036 * If a portion of path doesn’t exist, it’s created.
4037 * Arrays are created for missing index properties while objects are created
4038 * for all other missing properties.
4039 *
4040 * This function intentionally mutates the input object.
4041 *
4042 * Inspired by _.set().
4043 *
4044 * @see https://lodash.com/docs/4.17.15#set
4045 *
4046 * @param {Object} object Object to modify
4047 * @param {Array} path Path of the property to set.
4048 * @param {*} value Value to set.
4049 */
4050 function setNestedValue(object, path, value) {
4051 if (!object || typeof object !== 'object') {
4052 return object;
4053 }
4054
4055 path.reduce((acc, key, idx) => {
4056 if (acc[key] === undefined) {
4057 if (Number.isInteger(path[idx + 1])) {
4058 acc[key] = [];
4059 } else {
4060 acc[key] = {};
4061 }
4062 }
4063
4064 if (idx === path.length - 1) {
4065 acc[key] = value;
4066 }
4067
4068 return acc[key];
4069 }, object);
4070 return object;
4071 }
4072
4073 ;// CONCATENATED MODULE: ./packages/core-data/build-module/queried-data/selectors.js
4074 /**
4075 * External dependencies
4076 */
4077
4078
4079 /**
4080 * Internal dependencies
4081 */
4082
4083
4084
4085 /**
4086 * Cache of state keys to EquivalentKeyMap where the inner map tracks queries
4087 * to their resulting items set. WeakMap allows garbage collection on expired
4088 * state references.
4089 *
4090 * @type {WeakMap<Object,EquivalentKeyMap>}
4091 */
4092
4093 const queriedItemsCacheByState = new WeakMap();
4094 /**
4095 * Returns items for a given query, or null if the items are not known.
4096 *
4097 * @param {Object} state State object.
4098 * @param {?Object} query Optional query.
4099 *
4100 * @return {?Array} Query items.
4101 */
4102
4103 function getQueriedItemsUncached(state, query) {
4104 const {
4105 stableKey,
4106 page,
4107 perPage,
4108 include,
4109 fields,
4110 context
4111 } = get_query_parts(query);
4112 let itemIds;
4113
4114 if (state.queries?.[context]?.[stableKey]) {
4115 itemIds = state.queries[context][stableKey];
4116 }
4117
4118 if (!itemIds) {
4119 return null;
4120 }
4121
4122 const startOffset = perPage === -1 ? 0 : (page - 1) * perPage;
4123 const endOffset = perPage === -1 ? itemIds.length : Math.min(startOffset + perPage, itemIds.length);
4124 const items = [];
4125
4126 for (let i = startOffset; i < endOffset; i++) {
4127 const itemId = itemIds[i];
4128
4129 if (Array.isArray(include) && !include.includes(itemId)) {
4130 continue;
4131 } // Having a target item ID doesn't guarantee that this object has been queried.
4132
4133
4134 if (!state.items[context]?.hasOwnProperty(itemId)) {
4135 return null;
4136 }
4137
4138 const item = state.items[context][itemId];
4139 let filteredItem;
4140
4141 if (Array.isArray(fields)) {
4142 filteredItem = {};
4143
4144 for (let f = 0; f < fields.length; f++) {
4145 const field = fields[f].split('.');
4146 let value = item;
4147 field.forEach(fieldName => {
4148 value = value[fieldName];
4149 });
4150 setNestedValue(filteredItem, field, value);
4151 }
4152 } else {
4153 // If expecting a complete item, validate that completeness, or
4154 // otherwise abort.
4155 if (!state.itemIsComplete[context]?.[itemId]) {
4156 return null;
4157 }
4158
4159 filteredItem = item;
4160 }
4161
4162 items.push(filteredItem);
4163 }
4164
4165 return items;
4166 }
4167 /**
4168 * Returns items for a given query, or null if the items are not known. Caches
4169 * result both per state (by reference) and per query (by deep equality).
4170 * The caching approach is intended to be durable to query objects which are
4171 * deeply but not referentially equal, since otherwise:
4172 *
4173 * `getQueriedItems( state, {} ) !== getQueriedItems( state, {} )`
4174 *
4175 * @param {Object} state State object.
4176 * @param {?Object} query Optional query.
4177 *
4178 * @return {?Array} Query items.
4179 */
4180
4181
4182 const getQueriedItems = rememo((state, query = {}) => {
4183 let queriedItemsCache = queriedItemsCacheByState.get(state);
4184
4185 if (queriedItemsCache) {
4186 const queriedItems = queriedItemsCache.get(query);
4187
4188 if (queriedItems !== undefined) {
4189 return queriedItems;
4190 }
4191 } else {
4192 queriedItemsCache = new (equivalent_key_map_default())();
4193 queriedItemsCacheByState.set(state, queriedItemsCache);
4194 }
4195
4196 const items = getQueriedItemsUncached(state, query);
4197 queriedItemsCache.set(query, items);
4198 return items;
4199 });
4200
4201 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/is-raw-attribute.js
4202 /**
4203 * Checks whether the attribute is a "raw" attribute or not.
4204 *
4205 * @param {Object} entity Entity record.
4206 * @param {string} attribute Attribute name.
4207 *
4208 * @return {boolean} Is the attribute raw
4209 */
4210 function isRawAttribute(entity, attribute) {
4211 return (entity.rawAttributes || []).includes(attribute);
4212 }
4213
4214 ;// CONCATENATED MODULE: ./packages/core-data/build-module/selectors.js
4215 /**
4216 * External dependencies
4217 */
4218
4219 /**
4220 * WordPress dependencies
4221 */
4222
4223
4224
4225
4226 /**
4227 * Internal dependencies
4228 */
4229
4230
4231
4232
4233
4234 // This is an incomplete, high-level approximation of the State type.
4235 // It makes the selectors slightly more safe, but is intended to evolve
4236 // into a more detailed representation over time.
4237 // See https://github.com/WordPress/gutenberg/pull/40025#discussion_r865410589 for more context.
4238
4239 /**
4240 * Shared reference to an empty object for cases where it is important to avoid
4241 * returning a new object reference on every invocation, as in a connected or
4242 * other pure component which performs `shouldComponentUpdate` check on props.
4243 * This should be used as a last resort, since the normalized data should be
4244 * maintained by the reducer result in state.
4245 */
4246 const EMPTY_OBJECT = {};
4247 /**
4248 * Returns true if a request is in progress for embed preview data, or false
4249 * otherwise.
4250 *
4251 * @param state Data state.
4252 * @param url URL the preview would be for.
4253 *
4254 * @return Whether a request is in progress for an embed preview.
4255 */
4256
4257 const isRequestingEmbedPreview = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (state, url) => {
4258 return select(STORE_NAME).isResolving('getEmbedPreview', [url]);
4259 });
4260 /**
4261 * Returns all available authors.
4262 *
4263 * @deprecated since 11.3. Callers should use `select( 'core' ).getUsers({ who: 'authors' })` instead.
4264 *
4265 * @param state Data state.
4266 * @param query Optional object of query parameters to
4267 * include with request. For valid query parameters see the [Users page](https://developer.wordpress.org/rest-api/reference/users/) in the REST API Handbook and see the arguments for [List Users](https://developer.wordpress.org/rest-api/reference/users/#list-users) and [Retrieve a User](https://developer.wordpress.org/rest-api/reference/users/#retrieve-a-user).
4268 * @return Authors list.
4269 */
4270
4271 function getAuthors(state, query) {
4272 external_wp_deprecated_default()("select( 'core' ).getAuthors()", {
4273 since: '5.9',
4274 alternative: "select( 'core' ).getUsers({ who: 'authors' })"
4275 });
4276 const path = (0,external_wp_url_namespaceObject.addQueryArgs)('/wp/v2/users/?who=authors&per_page=100', query);
4277 return getUserQueryResults(state, path);
4278 }
4279 /**
4280 * Returns the current user.
4281 *
4282 * @param state Data state.
4283 *
4284 * @return Current user object.
4285 */
4286
4287 function getCurrentUser(state) {
4288 return state.currentUser;
4289 }
4290 /**
4291 * Returns all the users returned by a query ID.
4292 *
4293 * @param state Data state.
4294 * @param queryID Query ID.
4295 *
4296 * @return Users list.
4297 */
4298
4299 const getUserQueryResults = rememo((state, queryID) => {
4300 var _state$users$queries$;
4301
4302 const queryResults = (_state$users$queries$ = state.users.queries[queryID]) !== null && _state$users$queries$ !== void 0 ? _state$users$queries$ : [];
4303 return queryResults.map(id => state.users.byId[id]);
4304 }, (state, queryID) => [state.users.queries[queryID], state.users.byId]);
4305 /**
4306 * Returns the loaded entities for the given kind.
4307 *
4308 * @deprecated since WordPress 6.0. Use getEntitiesConfig instead
4309 * @param state Data state.
4310 * @param kind Entity kind.
4311 *
4312 * @return Array of entities with config matching kind.
4313 */
4314
4315 function getEntitiesByKind(state, kind) {
4316 external_wp_deprecated_default()("wp.data.select( 'core' ).getEntitiesByKind()", {
4317 since: '6.0',
4318 alternative: "wp.data.select( 'core' ).getEntitiesConfig()"
4319 });
4320 return getEntitiesConfig(state, kind);
4321 }
4322 /**
4323 * Returns the loaded entities for the given kind.
4324 *
4325 * @param state Data state.
4326 * @param kind Entity kind.
4327 *
4328 * @return Array of entities with config matching kind.
4329 */
4330
4331 function getEntitiesConfig(state, kind) {
4332 return state.entities.config.filter(entity => entity.kind === kind);
4333 }
4334 /**
4335 * Returns the entity config given its kind and name.
4336 *
4337 * @deprecated since WordPress 6.0. Use getEntityConfig instead
4338 * @param state Data state.
4339 * @param kind Entity kind.
4340 * @param name Entity name.
4341 *
4342 * @return Entity config
4343 */
4344
4345 function getEntity(state, kind, name) {
4346 external_wp_deprecated_default()("wp.data.select( 'core' ).getEntity()", {
4347 since: '6.0',
4348 alternative: "wp.data.select( 'core' ).getEntityConfig()"
4349 });
4350 return getEntityConfig(state, kind, name);
4351 }
4352 /**
4353 * Returns the entity config given its kind and name.
4354 *
4355 * @param state Data state.
4356 * @param kind Entity kind.
4357 * @param name Entity name.
4358 *
4359 * @return Entity config
4360 */
4361
4362 function getEntityConfig(state, kind, name) {
4363 return state.entities.config?.find(config => config.kind === kind && config.name === name);
4364 }
4365 /**
4366 * GetEntityRecord is declared as a *callable interface* with
4367 * two signatures to work around the fact that TypeScript doesn't
4368 * allow currying generic functions:
4369 *
4370 * ```ts
4371 * type CurriedState = F extends ( state: any, ...args: infer P ) => infer R
4372 * ? ( ...args: P ) => R
4373 * : F;
4374 * type Selector = <K extends string | number>(
4375 * state: any,
4376 * kind: K,
4377 * key: K extends string ? 'string value' : false
4378 * ) => K;
4379 * type BadlyInferredSignature = CurriedState< Selector >
4380 * // BadlyInferredSignature evaluates to:
4381 * // (kind: string number, key: false | "string value") => string number
4382 * ```
4383 *
4384 * The signature without the state parameter shipped as CurriedSignature
4385 * is used in the return value of `select( coreStore )`.
4386 *
4387 * See https://github.com/WordPress/gutenberg/pull/41578 for more details.
4388 */
4389
4390 /**
4391 * Returns the Entity's record object by key. Returns `null` if the value is not
4392 * yet received, undefined if the value entity is known to not exist, or the
4393 * entity object if it exists and is received.
4394 *
4395 * @param state State tree
4396 * @param kind Entity kind.
4397 * @param name Entity name.
4398 * @param key Record's key
4399 * @param query Optional query. If requesting specific
4400 * fields, fields must always include the ID. For valid query parameters see the [Reference](https://developer.wordpress.org/rest-api/reference/) in the REST API Handbook and select the entity kind. Then see the arguments available "Retrieve a [Entity kind]".
4401 *
4402 * @return Record.
4403 */
4404 const getEntityRecord = rememo((state, kind, name, key, query) => {
4405 var _query$context;
4406
4407 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData;
4408
4409 if (!queriedState) {
4410 return undefined;
4411 }
4412
4413 const context = (_query$context = query?.context) !== null && _query$context !== void 0 ? _query$context : 'default';
4414
4415 if (query === undefined) {
4416 // If expecting a complete item, validate that completeness.
4417 if (!queriedState.itemIsComplete[context]?.[key]) {
4418 return undefined;
4419 }
4420
4421 return queriedState.items[context][key];
4422 }
4423
4424 const item = queriedState.items[context]?.[key];
4425
4426 if (item && query._fields) {
4427 var _getNormalizedCommaSe;
4428
4429 const filteredItem = {};
4430 const fields = (_getNormalizedCommaSe = get_normalized_comma_separable(query._fields)) !== null && _getNormalizedCommaSe !== void 0 ? _getNormalizedCommaSe : [];
4431
4432 for (let f = 0; f < fields.length; f++) {
4433 const field = fields[f].split('.');
4434 let value = item;
4435 field.forEach(fieldName => {
4436 value = value[fieldName];
4437 });
4438 setNestedValue(filteredItem, field, value);
4439 }
4440
4441 return filteredItem;
4442 }
4443
4444 return item;
4445 }, (state, kind, name, recordId, query) => {
4446 var _query$context2;
4447
4448 const context = (_query$context2 = query?.context) !== null && _query$context2 !== void 0 ? _query$context2 : 'default';
4449 return [state.entities.records?.[kind]?.[name]?.queriedData?.items[context]?.[recordId], state.entities.records?.[kind]?.[name]?.queriedData?.itemIsComplete[context]?.[recordId]];
4450 });
4451 /**
4452 * Returns the Entity's record object by key. Doesn't trigger a resolver nor requests the entity records from the API if the entity record isn't available in the local state.
4453 *
4454 * @param state State tree
4455 * @param kind Entity kind.
4456 * @param name Entity name.
4457 * @param key Record's key
4458 *
4459 * @return Record.
4460 */
4461
4462 function __experimentalGetEntityRecordNoResolver(state, kind, name, key) {
4463 return getEntityRecord(state, kind, name, key);
4464 }
4465 /**
4466 * Returns the entity's record object by key,
4467 * with its attributes mapped to their raw values.
4468 *
4469 * @param state State tree.
4470 * @param kind Entity kind.
4471 * @param name Entity name.
4472 * @param key Record's key.
4473 *
4474 * @return Object with the entity's raw attributes.
4475 */
4476
4477 const getRawEntityRecord = rememo((state, kind, name, key) => {
4478 const record = getEntityRecord(state, kind, name, key);
4479 return record && Object.keys(record).reduce((accumulator, _key) => {
4480 if (isRawAttribute(getEntityConfig(state, kind, name), _key)) {
4481 var _record$_key$raw;
4482
4483 // Because edits are the "raw" attribute values,
4484 // we return those from record selectors to make rendering,
4485 // comparisons, and joins with edits easier.
4486 accumulator[_key] = (_record$_key$raw = record[_key]?.raw) !== null && _record$_key$raw !== void 0 ? _record$_key$raw : record[_key];
4487 } else {
4488 accumulator[_key] = record[_key];
4489 }
4490
4491 return accumulator;
4492 }, {});
4493 }, (state, kind, name, recordId, query) => {
4494 var _query$context3;
4495
4496 const context = (_query$context3 = query?.context) !== null && _query$context3 !== void 0 ? _query$context3 : 'default';
4497 return [state.entities.config, state.entities.records?.[kind]?.[name]?.queriedData?.items[context]?.[recordId], state.entities.records?.[kind]?.[name]?.queriedData?.itemIsComplete[context]?.[recordId]];
4498 });
4499 /**
4500 * Returns true if records have been received for the given set of parameters,
4501 * or false otherwise.
4502 *
4503 * @param state State tree
4504 * @param kind Entity kind.
4505 * @param name Entity name.
4506 * @param query Optional terms query. For valid query parameters see the [Reference](https://developer.wordpress.org/rest-api/reference/) in the REST API Handbook and select the entity kind. Then see the arguments available for "List [Entity kind]s".
4507 *
4508 * @return Whether entity records have been received.
4509 */
4510
4511 function hasEntityRecords(state, kind, name, query) {
4512 return Array.isArray(getEntityRecords(state, kind, name, query));
4513 }
4514 /**
4515 * GetEntityRecord is declared as a *callable interface* with
4516 * two signatures to work around the fact that TypeScript doesn't
4517 * allow currying generic functions.
4518 *
4519 * @see GetEntityRecord
4520 * @see https://github.com/WordPress/gutenberg/pull/41578
4521 */
4522
4523 /**
4524 * Returns the Entity's records.
4525 *
4526 * @param state State tree
4527 * @param kind Entity kind.
4528 * @param name Entity name.
4529 * @param query Optional terms query. If requesting specific
4530 * fields, fields must always include the ID. For valid query parameters see the [Reference](https://developer.wordpress.org/rest-api/reference/) in the REST API Handbook and select the entity kind. Then see the arguments available for "List [Entity kind]s".
4531 *
4532 * @return Records.
4533 */
4534 const getEntityRecords = (state, kind, name, query) => {
4535 // Queried data state is prepopulated for all known entities. If this is not
4536 // assigned for the given parameters, then it is known to not exist.
4537 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData;
4538
4539 if (!queriedState) {
4540 return null;
4541 }
4542
4543 return getQueriedItems(queriedState, query);
4544 };
4545
4546 /**
4547 * Returns the list of dirty entity records.
4548 *
4549 * @param state State tree.
4550 *
4551 * @return The list of updated records
4552 */
4553 const __experimentalGetDirtyEntityRecords = rememo(state => {
4554 const {
4555 entities: {
4556 records
4557 }
4558 } = state;
4559 const dirtyRecords = [];
4560 Object.keys(records).forEach(kind => {
4561 Object.keys(records[kind]).forEach(name => {
4562 const primaryKeys = Object.keys(records[kind][name].edits).filter(primaryKey => // The entity record must exist (not be deleted),
4563 // and it must have edits.
4564 getEntityRecord(state, kind, name, primaryKey) && hasEditsForEntityRecord(state, kind, name, primaryKey));
4565
4566 if (primaryKeys.length) {
4567 const entityConfig = getEntityConfig(state, kind, name);
4568 primaryKeys.forEach(primaryKey => {
4569 const entityRecord = getEditedEntityRecord(state, kind, name, primaryKey);
4570 dirtyRecords.push({
4571 // We avoid using primaryKey because it's transformed into a string
4572 // when it's used as an object key.
4573 key: entityRecord ? entityRecord[entityConfig.key || DEFAULT_ENTITY_KEY] : undefined,
4574 title: entityConfig?.getTitle?.(entityRecord) || '',
4575 name,
4576 kind
4577 });
4578 });
4579 }
4580 });
4581 });
4582 return dirtyRecords;
4583 }, state => [state.entities.records]);
4584 /**
4585 * Returns the list of entities currently being saved.
4586 *
4587 * @param state State tree.
4588 *
4589 * @return The list of records being saved.
4590 */
4591
4592 const __experimentalGetEntitiesBeingSaved = rememo(state => {
4593 const {
4594 entities: {
4595 records
4596 }
4597 } = state;
4598 const recordsBeingSaved = [];
4599 Object.keys(records).forEach(kind => {
4600 Object.keys(records[kind]).forEach(name => {
4601 const primaryKeys = Object.keys(records[kind][name].saving).filter(primaryKey => isSavingEntityRecord(state, kind, name, primaryKey));
4602
4603 if (primaryKeys.length) {
4604 const entityConfig = getEntityConfig(state, kind, name);
4605 primaryKeys.forEach(primaryKey => {
4606 const entityRecord = getEditedEntityRecord(state, kind, name, primaryKey);
4607 recordsBeingSaved.push({
4608 // We avoid using primaryKey because it's transformed into a string
4609 // when it's used as an object key.
4610 key: entityRecord ? entityRecord[entityConfig.key || DEFAULT_ENTITY_KEY] : undefined,
4611 title: entityConfig?.getTitle?.(entityRecord) || '',
4612 name,
4613 kind
4614 });
4615 });
4616 }
4617 });
4618 });
4619 return recordsBeingSaved;
4620 }, state => [state.entities.records]);
4621 /**
4622 * Returns the specified entity record's edits.
4623 *
4624 * @param state State tree.
4625 * @param kind Entity kind.
4626 * @param name Entity name.
4627 * @param recordId Record ID.
4628 *
4629 * @return The entity record's edits.
4630 */
4631
4632 function getEntityRecordEdits(state, kind, name, recordId) {
4633 return state.entities.records?.[kind]?.[name]?.edits?.[recordId];
4634 }
4635 /**
4636 * Returns the specified entity record's non transient edits.
4637 *
4638 * Transient edits don't create an undo level, and
4639 * are not considered for change detection.
4640 * They are defined in the entity's config.
4641 *
4642 * @param state State tree.
4643 * @param kind Entity kind.
4644 * @param name Entity name.
4645 * @param recordId Record ID.
4646 *
4647 * @return The entity record's non transient edits.
4648 */
4649
4650 const getEntityRecordNonTransientEdits = rememo((state, kind, name, recordId) => {
4651 const {
4652 transientEdits
4653 } = getEntityConfig(state, kind, name) || {};
4654 const edits = getEntityRecordEdits(state, kind, name, recordId) || {};
4655
4656 if (!transientEdits) {
4657 return edits;
4658 }
4659
4660 return Object.keys(edits).reduce((acc, key) => {
4661 if (!transientEdits[key]) {
4662 acc[key] = edits[key];
4663 }
4664
4665 return acc;
4666 }, {});
4667 }, (state, kind, name, recordId) => [state.entities.config, state.entities.records?.[kind]?.[name]?.edits?.[recordId]]);
4668 /**
4669 * Returns true if the specified entity record has edits,
4670 * and false otherwise.
4671 *
4672 * @param state State tree.
4673 * @param kind Entity kind.
4674 * @param name Entity name.
4675 * @param recordId Record ID.
4676 *
4677 * @return Whether the entity record has edits or not.
4678 */
4679
4680 function hasEditsForEntityRecord(state, kind, name, recordId) {
4681 return isSavingEntityRecord(state, kind, name, recordId) || Object.keys(getEntityRecordNonTransientEdits(state, kind, name, recordId)).length > 0;
4682 }
4683 /**
4684 * Returns the specified entity record, merged with its edits.
4685 *
4686 * @param state State tree.
4687 * @param kind Entity kind.
4688 * @param name Entity name.
4689 * @param recordId Record ID.
4690 *
4691 * @return The entity record, merged with its edits.
4692 */
4693
4694 const getEditedEntityRecord = rememo((state, kind, name, recordId) => ({ ...getRawEntityRecord(state, kind, name, recordId),
4695 ...getEntityRecordEdits(state, kind, name, recordId)
4696 }), (state, kind, name, recordId, query) => {
4697 var _query$context4;
4698
4699 const context = (_query$context4 = query?.context) !== null && _query$context4 !== void 0 ? _query$context4 : 'default';
4700 return [state.entities.config, state.entities.records?.[kind]?.[name]?.queriedData.items[context]?.[recordId], state.entities.records?.[kind]?.[name]?.queriedData.itemIsComplete[context]?.[recordId], state.entities.records?.[kind]?.[name]?.edits?.[recordId]];
4701 });
4702 /**
4703 * Returns true if the specified entity record is autosaving, and false otherwise.
4704 *
4705 * @param state State tree.
4706 * @param kind Entity kind.
4707 * @param name Entity name.
4708 * @param recordId Record ID.
4709 *
4710 * @return Whether the entity record is autosaving or not.
4711 */
4712
4713 function isAutosavingEntityRecord(state, kind, name, recordId) {
4714 var _state$entities$recor;
4715
4716 const {
4717 pending,
4718 isAutosave
4719 } = (_state$entities$recor = state.entities.records?.[kind]?.[name]?.saving?.[recordId]) !== null && _state$entities$recor !== void 0 ? _state$entities$recor : {};
4720 return Boolean(pending && isAutosave);
4721 }
4722 /**
4723 * Returns true if the specified entity record is saving, and false otherwise.
4724 *
4725 * @param state State tree.
4726 * @param kind Entity kind.
4727 * @param name Entity name.
4728 * @param recordId Record ID.
4729 *
4730 * @return Whether the entity record is saving or not.
4731 */
4732
4733 function isSavingEntityRecord(state, kind, name, recordId) {
4734 var _state$entities$recor2;
4735
4736 return (_state$entities$recor2 = state.entities.records?.[kind]?.[name]?.saving?.[recordId]?.pending) !== null && _state$entities$recor2 !== void 0 ? _state$entities$recor2 : false;
4737 }
4738 /**
4739 * Returns true if the specified entity record is deleting, and false otherwise.
4740 *
4741 * @param state State tree.
4742 * @param kind Entity kind.
4743 * @param name Entity name.
4744 * @param recordId Record ID.
4745 *
4746 * @return Whether the entity record is deleting or not.
4747 */
4748
4749 function isDeletingEntityRecord(state, kind, name, recordId) {
4750 var _state$entities$recor3;
4751
4752 return (_state$entities$recor3 = state.entities.records?.[kind]?.[name]?.deleting?.[recordId]?.pending) !== null && _state$entities$recor3 !== void 0 ? _state$entities$recor3 : false;
4753 }
4754 /**
4755 * Returns the specified entity record's last save error.
4756 *
4757 * @param state State tree.
4758 * @param kind Entity kind.
4759 * @param name Entity name.
4760 * @param recordId Record ID.
4761 *
4762 * @return The entity record's save error.
4763 */
4764
4765 function getLastEntitySaveError(state, kind, name, recordId) {
4766 return state.entities.records?.[kind]?.[name]?.saving?.[recordId]?.error;
4767 }
4768 /**
4769 * Returns the specified entity record's last delete error.
4770 *
4771 * @param state State tree.
4772 * @param kind Entity kind.
4773 * @param name Entity name.
4774 * @param recordId Record ID.
4775 *
4776 * @return The entity record's save error.
4777 */
4778
4779 function getLastEntityDeleteError(state, kind, name, recordId) {
4780 return state.entities.records?.[kind]?.[name]?.deleting?.[recordId]?.error;
4781 }
4782 /**
4783 * Returns the current undo offset for the
4784 * entity records edits history. The offset
4785 * represents how many items from the end
4786 * of the history stack we are at. 0 is the
4787 * last edit, -1 is the second last, and so on.
4788 *
4789 * @param state State tree.
4790 *
4791 * @return The current undo offset.
4792 */
4793
4794 function getCurrentUndoOffset(state) {
4795 return state.undo.offset;
4796 }
4797 /**
4798 * Returns the previous edit from the current undo offset
4799 * for the entity records edits history, if any.
4800 *
4801 * @deprecated since 6.3
4802 *
4803 * @param state State tree.
4804 *
4805 * @return The edit.
4806 */
4807
4808
4809 function getUndoEdit(state) {
4810 external_wp_deprecated_default()("select( 'core' ).getUndoEdit()", {
4811 since: '6.3'
4812 });
4813 return state.undo.list[state.undo.list.length - 2 + getCurrentUndoOffset(state)]?.[0];
4814 }
4815 /**
4816 * Returns the next edit from the current undo offset
4817 * for the entity records edits history, if any.
4818 *
4819 * @deprecated since 6.3
4820 *
4821 * @param state State tree.
4822 *
4823 * @return The edit.
4824 */
4825
4826 function getRedoEdit(state) {
4827 external_wp_deprecated_default()("select( 'core' ).getRedoEdit()", {
4828 since: '6.3'
4829 });
4830 return state.undo.list[state.undo.list.length + getCurrentUndoOffset(state)]?.[0];
4831 }
4832 /**
4833 * Returns true if there is a previous edit from the current undo offset
4834 * for the entity records edits history, and false otherwise.
4835 *
4836 * @param state State tree.
4837 *
4838 * @return Whether there is a previous edit or not.
4839 */
4840
4841 function hasUndo(state) {
4842 return Boolean(getUndoEdits(state));
4843 }
4844 /**
4845 * Returns true if there is a next edit from the current undo offset
4846 * for the entity records edits history, and false otherwise.
4847 *
4848 * @param state State tree.
4849 *
4850 * @return Whether there is a next edit or not.
4851 */
4852
4853 function hasRedo(state) {
4854 return Boolean(getRedoEdits(state));
4855 }
4856 /**
4857 * Return the current theme.
4858 *
4859 * @param state Data state.
4860 *
4861 * @return The current theme.
4862 */
4863
4864 function getCurrentTheme(state) {
4865 return getEntityRecord(state, 'root', 'theme', state.currentTheme);
4866 }
4867 /**
4868 * Return the ID of the current global styles object.
4869 *
4870 * @param state Data state.
4871 *
4872 * @return The current global styles ID.
4873 */
4874
4875 function __experimentalGetCurrentGlobalStylesId(state) {
4876 return state.currentGlobalStylesId;
4877 }
4878 /**
4879 * Return theme supports data in the index.
4880 *
4881 * @param state Data state.
4882 *
4883 * @return Index data.
4884 */
4885
4886 function getThemeSupports(state) {
4887 var _getCurrentTheme$them;
4888
4889 return (_getCurrentTheme$them = getCurrentTheme(state)?.theme_supports) !== null && _getCurrentTheme$them !== void 0 ? _getCurrentTheme$them : EMPTY_OBJECT;
4890 }
4891 /**
4892 * Returns the embed preview for the given URL.
4893 *
4894 * @param state Data state.
4895 * @param url Embedded URL.
4896 *
4897 * @return Undefined if the preview has not been fetched, otherwise, the preview fetched from the embed preview API.
4898 */
4899
4900 function getEmbedPreview(state, url) {
4901 return state.embedPreviews[url];
4902 }
4903 /**
4904 * Determines if the returned preview is an oEmbed link fallback.
4905 *
4906 * WordPress can be configured to return a simple link to a URL if it is not embeddable.
4907 * We need to be able to determine if a URL is embeddable or not, based on what we
4908 * get back from the oEmbed preview API.
4909 *
4910 * @param state Data state.
4911 * @param url Embedded URL.
4912 *
4913 * @return Is the preview for the URL an oEmbed link fallback.
4914 */
4915
4916 function isPreviewEmbedFallback(state, url) {
4917 const preview = state.embedPreviews[url];
4918 const oEmbedLinkCheck = '<a href="' + url + '">' + url + '</a>';
4919
4920 if (!preview) {
4921 return false;
4922 }
4923
4924 return preview.html === oEmbedLinkCheck;
4925 }
4926 /**
4927 * Returns whether the current user can perform the given action on the given
4928 * REST resource.
4929 *
4930 * Calling this may trigger an OPTIONS request to the REST API via the
4931 * `canUser()` resolver.
4932 *
4933 * https://developer.wordpress.org/rest-api/reference/
4934 *
4935 * @param state Data state.
4936 * @param action Action to check. One of: 'create', 'read', 'update', 'delete'.
4937 * @param resource REST resource to check, e.g. 'media' or 'posts'.
4938 * @param id Optional ID of the rest resource to check.
4939 *
4940 * @return Whether or not the user can perform the action,
4941 * or `undefined` if the OPTIONS request is still being made.
4942 */
4943
4944 function canUser(state, action, resource, id) {
4945 const key = [action, resource, id].filter(Boolean).join('/');
4946 return state.userPermissions[key];
4947 }
4948 /**
4949 * Returns whether the current user can edit the given entity.
4950 *
4951 * Calling this may trigger an OPTIONS request to the REST API via the
4952 * `canUser()` resolver.
4953 *
4954 * https://developer.wordpress.org/rest-api/reference/
4955 *
4956 * @param state Data state.
4957 * @param kind Entity kind.
4958 * @param name Entity name.
4959 * @param recordId Record's id.
4960 * @return Whether or not the user can edit,
4961 * or `undefined` if the OPTIONS request is still being made.
4962 */
4963
4964 function canUserEditEntityRecord(state, kind, name, recordId) {
4965 const entityConfig = getEntityConfig(state, kind, name);
4966
4967 if (!entityConfig) {
4968 return false;
4969 }
4970
4971 const resource = entityConfig.__unstable_rest_base;
4972 return canUser(state, 'update', resource, recordId);
4973 }
4974 /**
4975 * Returns the latest autosaves for the post.
4976 *
4977 * May return multiple autosaves since the backend stores one autosave per
4978 * author for each post.
4979 *
4980 * @param state State tree.
4981 * @param postType The type of the parent post.
4982 * @param postId The id of the parent post.
4983 *
4984 * @return An array of autosaves for the post, or undefined if there is none.
4985 */
4986
4987 function getAutosaves(state, postType, postId) {
4988 return state.autosaves[postId];
4989 }
4990 /**
4991 * Returns the autosave for the post and author.
4992 *
4993 * @param state State tree.
4994 * @param postType The type of the parent post.
4995 * @param postId The id of the parent post.
4996 * @param authorId The id of the author.
4997 *
4998 * @return The autosave for the post and author.
4999 */
5000
5001 function getAutosave(state, postType, postId, authorId) {
5002 if (authorId === undefined) {
5003 return;
5004 }
5005
5006 const autosaves = state.autosaves[postId];
5007 return autosaves?.find(autosave => autosave.author === authorId);
5008 }
5009 /**
5010 * Returns true if the REST request for autosaves has completed.
5011 *
5012 * @param state State tree.
5013 * @param postType The type of the parent post.
5014 * @param postId The id of the parent post.
5015 *
5016 * @return True if the REST request was completed. False otherwise.
5017 */
5018
5019 const hasFetchedAutosaves = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (state, postType, postId) => {
5020 return select(STORE_NAME).hasFinishedResolution('getAutosaves', [postType, postId]);
5021 });
5022 /**
5023 * Returns a new reference when edited values have changed. This is useful in
5024 * inferring where an edit has been made between states by comparison of the
5025 * return values using strict equality.
5026 *
5027 * @example
5028 *
5029 * ```
5030 * const hasEditOccurred = (
5031 * getReferenceByDistinctEdits( beforeState ) !==
5032 * getReferenceByDistinctEdits( afterState )
5033 * );
5034 * ```
5035 *
5036 * @param state Editor state.
5037 *
5038 * @return A value whose reference will change only when an edit occurs.
5039 */
5040
5041 const getReferenceByDistinctEdits = rememo( // This unused state argument is listed here for the documentation generating tool (docgen).
5042 state => [], state => [state.undo.list.length, state.undo.offset]);
5043 /**
5044 * Retrieve the frontend template used for a given link.
5045 *
5046 * @param state Editor state.
5047 * @param link Link.
5048 *
5049 * @return The template record.
5050 */
5051
5052 function __experimentalGetTemplateForLink(state, link) {
5053 const records = getEntityRecords(state, 'postType', 'wp_template', {
5054 'find-template': link
5055 });
5056
5057 if (records?.length) {
5058 return getEditedEntityRecord(state, 'postType', 'wp_template', records[0].id);
5059 }
5060
5061 return null;
5062 }
5063 /**
5064 * Retrieve the current theme's base global styles
5065 *
5066 * @param state Editor state.
5067 *
5068 * @return The Global Styles object.
5069 */
5070
5071 function __experimentalGetCurrentThemeBaseGlobalStyles(state) {
5072 const currentTheme = getCurrentTheme(state);
5073
5074 if (!currentTheme) {
5075 return null;
5076 }
5077
5078 return state.themeBaseGlobalStyles[currentTheme.stylesheet];
5079 }
5080 /**
5081 * Return the ID of the current global styles object.
5082 *
5083 * @param state Data state.
5084 *
5085 * @return The current global styles ID.
5086 */
5087
5088 function __experimentalGetCurrentThemeGlobalStylesVariations(state) {
5089 const currentTheme = getCurrentTheme(state);
5090
5091 if (!currentTheme) {
5092 return null;
5093 }
5094
5095 return state.themeGlobalStyleVariations[currentTheme.stylesheet];
5096 }
5097 /**
5098 * Retrieve the list of registered block patterns.
5099 *
5100 * @param state Data state.
5101 *
5102 * @return Block pattern list.
5103 */
5104
5105 function getBlockPatterns(state) {
5106 return state.blockPatterns;
5107 }
5108 /**
5109 * Retrieve the list of registered block pattern categories.
5110 *
5111 * @param state Data state.
5112 *
5113 * @return Block pattern category list.
5114 */
5115
5116 function getBlockPatternCategories(state) {
5117 return state.blockPatternCategories;
5118 }
5119 /**
5120 * Returns the revisions of the current global styles theme.
5121 *
5122 * @param state Data state.
5123 *
5124 * @return The current global styles.
5125 */
5126
5127 function getCurrentThemeGlobalStylesRevisions(state) {
5128 const currentGlobalStylesId = __experimentalGetCurrentGlobalStylesId(state);
5129
5130 if (!currentGlobalStylesId) {
5131 return null;
5132 }
5133
5134 return state.themeGlobalStyleRevisions[currentGlobalStylesId];
5135 }
5136
5137 ;// CONCATENATED MODULE: ./node_modules/camel-case/dist.es2015/index.js
5138
5139
5140 function camelCaseTransform(input, index) {
5141 if (index === 0)
5142 return input.toLowerCase();
5143 return pascalCaseTransform(input, index);
5144 }
5145 function camelCaseTransformMerge(input, index) {
5146 if (index === 0)
5147 return input.toLowerCase();
5148 return pascalCaseTransformMerge(input);
5149 }
5150 function camelCase(input, options) {
5151 if (options === void 0) { options = {}; }
5152 return pascalCase(input, __assign({ transform: camelCaseTransform }, options));
5153 }
5154
5155 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/forward-resolver.js
5156 /**
5157 * Higher-order function which forward the resolution to another resolver with the same arguments.
5158 *
5159 * @param {string} resolverName forwarded resolver.
5160 *
5161 * @return {Function} Enhanced resolver.
5162 */
5163 const forwardResolver = resolverName => (...args) => async ({
5164 resolveSelect
5165 }) => {
5166 await resolveSelect[resolverName](...args);
5167 };
5168
5169 /* harmony default export */ const forward_resolver = (forwardResolver);
5170
5171 ;// CONCATENATED MODULE: ./packages/core-data/build-module/resolvers.js
5172 /**
5173 * External dependencies
5174 */
5175
5176 /**
5177 * WordPress dependencies
5178 */
5179
5180
5181
5182 /**
5183 * Internal dependencies
5184 */
5185
5186
5187
5188
5189 /**
5190 * Requests authors from the REST API.
5191 *
5192 * @param {Object|undefined} query Optional object of query parameters to
5193 * include with request.
5194 */
5195
5196 const resolvers_getAuthors = query => async ({
5197 dispatch
5198 }) => {
5199 const path = (0,external_wp_url_namespaceObject.addQueryArgs)('/wp/v2/users/?who=authors&per_page=100', query);
5200 const users = await external_wp_apiFetch_default()({
5201 path
5202 });
5203 dispatch.receiveUserQuery(path, users);
5204 };
5205 /**
5206 * Requests the current user from the REST API.
5207 */
5208
5209 const resolvers_getCurrentUser = () => async ({
5210 dispatch
5211 }) => {
5212 const currentUser = await external_wp_apiFetch_default()({
5213 path: '/wp/v2/users/me'
5214 });
5215 dispatch.receiveCurrentUser(currentUser);
5216 };
5217 /**
5218 * Requests an entity's record from the REST API.
5219 *
5220 * @param {string} kind Entity kind.
5221 * @param {string} name Entity name.
5222 * @param {number|string} key Record's key
5223 * @param {Object|undefined} query Optional object of query parameters to
5224 * include with request. If requesting specific
5225 * fields, fields must always include the ID.
5226 */
5227
5228 const resolvers_getEntityRecord = (kind, name, key = '', query) => async ({
5229 select,
5230 dispatch
5231 }) => {
5232 const configs = await dispatch(getOrLoadEntitiesConfig(kind));
5233 const entityConfig = configs.find(config => config.name === name && config.kind === kind);
5234
5235 if (!entityConfig || entityConfig?.__experimentalNoFetch) {
5236 return;
5237 }
5238
5239 const lock = await dispatch.__unstableAcquireStoreLock(STORE_NAME, ['entities', 'records', kind, name, key], {
5240 exclusive: false
5241 });
5242
5243 try {
5244 if (query !== undefined && query._fields) {
5245 // If requesting specific fields, items and query association to said
5246 // records are stored by ID reference. Thus, fields must always include
5247 // the ID.
5248 query = { ...query,
5249 _fields: [...new Set([...(get_normalized_comma_separable(query._fields) || []), entityConfig.key || DEFAULT_ENTITY_KEY])].join()
5250 };
5251 } // Disable reason: While true that an early return could leave `path`
5252 // unused, it's important that path is derived using the query prior to
5253 // additional query modifications in the condition below, since those
5254 // modifications are relevant to how the data is tracked in state, and not
5255 // for how the request is made to the REST API.
5256 // eslint-disable-next-line @wordpress/no-unused-vars-before-return
5257
5258
5259 const path = (0,external_wp_url_namespaceObject.addQueryArgs)(entityConfig.baseURL + (key ? '/' + key : ''), { ...entityConfig.baseURLParams,
5260 ...query
5261 });
5262
5263 if (query !== undefined) {
5264 query = { ...query,
5265 include: [key]
5266 }; // The resolution cache won't consider query as reusable based on the
5267 // fields, so it's tested here, prior to initiating the REST request,
5268 // and without causing `getEntityRecords` resolution to occur.
5269
5270 const hasRecords = select.hasEntityRecords(kind, name, query);
5271
5272 if (hasRecords) {
5273 return;
5274 }
5275 }
5276
5277 const record = await external_wp_apiFetch_default()({
5278 path
5279 });
5280 dispatch.receiveEntityRecords(kind, name, record, query);
5281 } finally {
5282 dispatch.__unstableReleaseStoreLock(lock);
5283 }
5284 };
5285 /**
5286 * Requests an entity's record from the REST API.
5287 */
5288
5289 const resolvers_getRawEntityRecord = forward_resolver('getEntityRecord');
5290 /**
5291 * Requests an entity's record from the REST API.
5292 */
5293
5294 const resolvers_getEditedEntityRecord = forward_resolver('getEntityRecord');
5295 /**
5296 * Requests the entity's records from the REST API.
5297 *
5298 * @param {string} kind Entity kind.
5299 * @param {string} name Entity name.
5300 * @param {Object?} query Query Object. If requesting specific fields, fields
5301 * must always include the ID.
5302 */
5303
5304 const resolvers_getEntityRecords = (kind, name, query = {}) => async ({
5305 dispatch
5306 }) => {
5307 const configs = await dispatch(getOrLoadEntitiesConfig(kind));
5308 const entityConfig = configs.find(config => config.name === name && config.kind === kind);
5309
5310 if (!entityConfig || entityConfig?.__experimentalNoFetch) {
5311 return;
5312 }
5313
5314 const lock = await dispatch.__unstableAcquireStoreLock(STORE_NAME, ['entities', 'records', kind, name], {
5315 exclusive: false
5316 });
5317
5318 try {
5319 if (query._fields) {
5320 // If requesting specific fields, items and query association to said
5321 // records are stored by ID reference. Thus, fields must always include
5322 // the ID.
5323 query = { ...query,
5324 _fields: [...new Set([...(get_normalized_comma_separable(query._fields) || []), entityConfig.key || DEFAULT_ENTITY_KEY])].join()
5325 };
5326 }
5327
5328 const path = (0,external_wp_url_namespaceObject.addQueryArgs)(entityConfig.baseURL, { ...entityConfig.baseURLParams,
5329 ...query
5330 });
5331 let records = Object.values(await external_wp_apiFetch_default()({
5332 path
5333 })); // If we request fields but the result doesn't contain the fields,
5334 // explicitly set these fields as "undefined"
5335 // that way we consider the query "fullfilled".
5336
5337 if (query._fields) {
5338 records = records.map(record => {
5339 query._fields.split(',').forEach(field => {
5340 if (!record.hasOwnProperty(field)) {
5341 record[field] = undefined;
5342 }
5343 });
5344
5345 return record;
5346 });
5347 }
5348
5349 dispatch.receiveEntityRecords(kind, name, records, query); // When requesting all fields, the list of results can be used to
5350 // resolve the `getEntityRecord` selector in addition to `getEntityRecords`.
5351 // See https://github.com/WordPress/gutenberg/pull/26575
5352
5353 if (!query?._fields && !query.context) {
5354 const key = entityConfig.key || DEFAULT_ENTITY_KEY;
5355 const resolutionsArgs = records.filter(record => record[key]).map(record => [kind, name, record[key]]);
5356 dispatch({
5357 type: 'START_RESOLUTIONS',
5358 selectorName: 'getEntityRecord',
5359 args: resolutionsArgs
5360 });
5361 dispatch({
5362 type: 'FINISH_RESOLUTIONS',
5363 selectorName: 'getEntityRecord',
5364 args: resolutionsArgs
5365 });
5366 }
5367 } finally {
5368 dispatch.__unstableReleaseStoreLock(lock);
5369 }
5370 };
5371
5372 resolvers_getEntityRecords.shouldInvalidate = (action, kind, name) => {
5373 return (action.type === 'RECEIVE_ITEMS' || action.type === 'REMOVE_ITEMS') && action.invalidateCache && kind === action.kind && name === action.name;
5374 };
5375 /**
5376 * Requests the current theme.
5377 */
5378
5379
5380 const resolvers_getCurrentTheme = () => async ({
5381 dispatch,
5382 resolveSelect
5383 }) => {
5384 const activeThemes = await resolveSelect.getEntityRecords('root', 'theme', {
5385 status: 'active'
5386 });
5387 dispatch.receiveCurrentTheme(activeThemes[0]);
5388 };
5389 /**
5390 * Requests theme supports data from the index.
5391 */
5392
5393 const resolvers_getThemeSupports = forward_resolver('getCurrentTheme');
5394 /**
5395 * Requests a preview from the from the Embed API.
5396 *
5397 * @param {string} url URL to get the preview for.
5398 */
5399
5400 const resolvers_getEmbedPreview = url => async ({
5401 dispatch
5402 }) => {
5403 try {
5404 const embedProxyResponse = await external_wp_apiFetch_default()({
5405 path: (0,external_wp_url_namespaceObject.addQueryArgs)('/oembed/1.0/proxy', {
5406 url
5407 })
5408 });
5409 dispatch.receiveEmbedPreview(url, embedProxyResponse);
5410 } catch (error) {
5411 // Embed API 404s if the URL cannot be embedded, so we have to catch the error from the apiRequest here.
5412 dispatch.receiveEmbedPreview(url, false);
5413 }
5414 };
5415 /**
5416 * Checks whether the current user can perform the given action on the given
5417 * REST resource.
5418 *
5419 * @param {string} requestedAction Action to check. One of: 'create', 'read', 'update',
5420 * 'delete'.
5421 * @param {string} resource REST resource to check, e.g. 'media' or 'posts'.
5422 * @param {?string} id ID of the rest resource to check.
5423 */
5424
5425 const resolvers_canUser = (requestedAction, resource, id) => async ({
5426 dispatch,
5427 registry
5428 }) => {
5429 const {
5430 hasStartedResolution
5431 } = registry.select(STORE_NAME);
5432 const resourcePath = id ? `${resource}/${id}` : resource;
5433 const retrievedActions = ['create', 'read', 'update', 'delete'];
5434
5435 if (!retrievedActions.includes(requestedAction)) {
5436 throw new Error(`'${requestedAction}' is not a valid action.`);
5437 } // Prevent resolving the same resource twice.
5438
5439
5440 for (const relatedAction of retrievedActions) {
5441 if (relatedAction === requestedAction) {
5442 continue;
5443 }
5444
5445 const isAlreadyResolving = hasStartedResolution('canUser', [relatedAction, resource, id]);
5446
5447 if (isAlreadyResolving) {
5448 return;
5449 }
5450 }
5451
5452 let response;
5453
5454 try {
5455 response = await external_wp_apiFetch_default()({
5456 path: `/wp/v2/${resourcePath}`,
5457 method: 'OPTIONS',
5458 parse: false
5459 });
5460 } catch (error) {
5461 // Do nothing if our OPTIONS request comes back with an API error (4xx or
5462 // 5xx). The previously determined isAllowed value will remain in the store.
5463 return;
5464 } // Optional chaining operator is used here because the API requests don't
5465 // return the expected result in the native version. Instead, API requests
5466 // only return the result, without including response properties like the headers.
5467
5468
5469 const allowHeader = response.headers?.get('allow');
5470 const allowedMethods = allowHeader?.allow || allowHeader || '';
5471 const permissions = {};
5472 const methods = {
5473 create: 'POST',
5474 read: 'GET',
5475 update: 'PUT',
5476 delete: 'DELETE'
5477 };
5478
5479 for (const [actionName, methodName] of Object.entries(methods)) {
5480 permissions[actionName] = allowedMethods.includes(methodName);
5481 }
5482
5483 for (const action of retrievedActions) {
5484 dispatch.receiveUserPermission(`${action}/${resourcePath}`, permissions[action]);
5485 }
5486 };
5487 /**
5488 * Checks whether the current user can perform the given action on the given
5489 * REST resource.
5490 *
5491 * @param {string} kind Entity kind.
5492 * @param {string} name Entity name.
5493 * @param {string} recordId Record's id.
5494 */
5495
5496 const resolvers_canUserEditEntityRecord = (kind, name, recordId) => async ({
5497 dispatch
5498 }) => {
5499 const configs = await dispatch(getOrLoadEntitiesConfig(kind));
5500 const entityConfig = configs.find(config => config.name === name && config.kind === kind);
5501
5502 if (!entityConfig) {
5503 return;
5504 }
5505
5506 const resource = entityConfig.__unstable_rest_base;
5507 await dispatch(resolvers_canUser('update', resource, recordId));
5508 };
5509 /**
5510 * Request autosave data from the REST API.
5511 *
5512 * @param {string} postType The type of the parent post.
5513 * @param {number} postId The id of the parent post.
5514 */
5515
5516 const resolvers_getAutosaves = (postType, postId) => async ({
5517 dispatch,
5518 resolveSelect
5519 }) => {
5520 const {
5521 rest_base: restBase,
5522 rest_namespace: restNamespace = 'wp/v2'
5523 } = await resolveSelect.getPostType(postType);
5524 const autosaves = await external_wp_apiFetch_default()({
5525 path: `/${restNamespace}/${restBase}/${postId}/autosaves?context=edit`
5526 });
5527
5528 if (autosaves && autosaves.length) {
5529 dispatch.receiveAutosaves(postId, autosaves);
5530 }
5531 };
5532 /**
5533 * Request autosave data from the REST API.
5534 *
5535 * This resolver exists to ensure the underlying autosaves are fetched via
5536 * `getAutosaves` when a call to the `getAutosave` selector is made.
5537 *
5538 * @param {string} postType The type of the parent post.
5539 * @param {number} postId The id of the parent post.
5540 */
5541
5542 const resolvers_getAutosave = (postType, postId) => async ({
5543 resolveSelect
5544 }) => {
5545 await resolveSelect.getAutosaves(postType, postId);
5546 };
5547 /**
5548 * Retrieve the frontend template used for a given link.
5549 *
5550 * @param {string} link Link.
5551 */
5552
5553 const resolvers_experimentalGetTemplateForLink = link => async ({
5554 dispatch,
5555 resolveSelect
5556 }) => {
5557 let template;
5558
5559 try {
5560 // This is NOT calling a REST endpoint but rather ends up with a response from
5561 // an Ajax function which has a different shape from a WP_REST_Response.
5562 template = await external_wp_apiFetch_default()({
5563 url: (0,external_wp_url_namespaceObject.addQueryArgs)(link, {
5564 '_wp-find-template': true
5565 })
5566 }).then(({
5567 data
5568 }) => data);
5569 } catch (e) {// For non-FSE themes, it is possible that this request returns an error.
5570 }
5571
5572 if (!template) {
5573 return;
5574 }
5575
5576 const record = await resolveSelect.getEntityRecord('postType', 'wp_template', template.id);
5577
5578 if (record) {
5579 dispatch.receiveEntityRecords('postType', 'wp_template', [record], {
5580 'find-template': link
5581 });
5582 }
5583 };
5584
5585 resolvers_experimentalGetTemplateForLink.shouldInvalidate = action => {
5586 return (action.type === 'RECEIVE_ITEMS' || action.type === 'REMOVE_ITEMS') && action.invalidateCache && action.kind === 'postType' && action.name === 'wp_template';
5587 };
5588
5589 const resolvers_experimentalGetCurrentGlobalStylesId = () => async ({
5590 dispatch,
5591 resolveSelect
5592 }) => {
5593 const activeThemes = await resolveSelect.getEntityRecords('root', 'theme', {
5594 status: 'active'
5595 });
5596 const globalStylesURL = activeThemes?.[0]?._links?.['wp:user-global-styles']?.[0]?.href;
5597
5598 if (globalStylesURL) {
5599 const globalStylesObject = await external_wp_apiFetch_default()({
5600 url: globalStylesURL
5601 });
5602
5603 dispatch.__experimentalReceiveCurrentGlobalStylesId(globalStylesObject.id);
5604 }
5605 };
5606 const resolvers_experimentalGetCurrentThemeBaseGlobalStyles = () => async ({
5607 resolveSelect,
5608 dispatch
5609 }) => {
5610 const currentTheme = await resolveSelect.getCurrentTheme();
5611 const themeGlobalStyles = await external_wp_apiFetch_default()({
5612 path: `/wp/v2/global-styles/themes/${currentTheme.stylesheet}`
5613 });
5614
5615 dispatch.__experimentalReceiveThemeBaseGlobalStyles(currentTheme.stylesheet, themeGlobalStyles);
5616 };
5617 const resolvers_experimentalGetCurrentThemeGlobalStylesVariations = () => async ({
5618 resolveSelect,
5619 dispatch
5620 }) => {
5621 const currentTheme = await resolveSelect.getCurrentTheme();
5622 const variations = await external_wp_apiFetch_default()({
5623 path: `/wp/v2/global-styles/themes/${currentTheme.stylesheet}/variations`
5624 });
5625
5626 dispatch.__experimentalReceiveThemeGlobalStyleVariations(currentTheme.stylesheet, variations);
5627 };
5628 /**
5629 * Fetches and returns the revisions of the current global styles theme.
5630 */
5631
5632 const resolvers_getCurrentThemeGlobalStylesRevisions = () => async ({
5633 resolveSelect,
5634 dispatch
5635 }) => {
5636 const globalStylesId = await resolveSelect.__experimentalGetCurrentGlobalStylesId();
5637 const record = globalStylesId ? await resolveSelect.getEntityRecord('root', 'globalStyles', globalStylesId) : undefined;
5638 const revisionsURL = record?._links?.['version-history']?.[0]?.href;
5639
5640 if (revisionsURL) {
5641 const resetRevisions = await external_wp_apiFetch_default()({
5642 url: revisionsURL
5643 });
5644 const revisions = resetRevisions?.map(revision => Object.fromEntries(Object.entries(revision).map(([key, value]) => [camelCase(key), value])));
5645 dispatch.receiveThemeGlobalStyleRevisions(globalStylesId, revisions);
5646 }
5647 };
5648
5649 resolvers_getCurrentThemeGlobalStylesRevisions.shouldInvalidate = action => {
5650 return action.type === 'SAVE_ENTITY_RECORD_FINISH' && action.kind === 'root' && !action.error && action.name === 'globalStyles';
5651 };
5652
5653 const resolvers_getBlockPatterns = () => async ({
5654 dispatch
5655 }) => {
5656 const restPatterns = await external_wp_apiFetch_default()({
5657 path: '/wp/v2/block-patterns/patterns'
5658 });
5659 const patterns = restPatterns?.map(pattern => Object.fromEntries(Object.entries(pattern).map(([key, value]) => [camelCase(key), value])));
5660 dispatch({
5661 type: 'RECEIVE_BLOCK_PATTERNS',
5662 patterns
5663 });
5664 };
5665 const resolvers_getBlockPatternCategories = () => async ({
5666 dispatch
5667 }) => {
5668 const categories = await external_wp_apiFetch_default()({
5669 path: '/wp/v2/block-patterns/categories'
5670 });
5671 dispatch({
5672 type: 'RECEIVE_BLOCK_PATTERN_CATEGORIES',
5673 categories
5674 });
5675 };
5676 const resolvers_getNavigationFallbackId = () => async ({
5677 dispatch,
5678 select
5679 }) => {
5680 const fallback = await external_wp_apiFetch_default()({
5681 path: (0,external_wp_url_namespaceObject.addQueryArgs)('/wp-block-editor/v1/navigation-fallback', {
5682 _embed: true
5683 })
5684 });
5685 const record = fallback?._embedded?.self;
5686 dispatch.receiveNavigationFallbackId(fallback?.id);
5687
5688 if (record) {
5689 // If the fallback is already in the store, don't invalidate navigation queries.
5690 // Otherwise, invalidate the cache for the scenario where there were no Navigation
5691 // posts in the state and the fallback created one.
5692 const existingFallbackEntityRecord = select.getEntityRecord('postType', 'wp_navigation', fallback?.id);
5693 const invalidateNavigationQueries = !existingFallbackEntityRecord;
5694 dispatch.receiveEntityRecords('postType', 'wp_navigation', record, undefined, invalidateNavigationQueries); // Resolve to avoid further network requests.
5695
5696 dispatch.finishResolution('getEntityRecord', ['postType', 'wp_navigation', fallback?.id]);
5697 }
5698 };
5699
5700 ;// CONCATENATED MODULE: ./packages/core-data/build-module/locks/utils.js
5701 function deepCopyLocksTreePath(tree, path) {
5702 const newTree = { ...tree
5703 };
5704 let currentNode = newTree;
5705
5706 for (const branchName of path) {
5707 currentNode.children = { ...currentNode.children,
5708 [branchName]: {
5709 locks: [],
5710 children: {},
5711 ...currentNode.children[branchName]
5712 }
5713 };
5714 currentNode = currentNode.children[branchName];
5715 }
5716
5717 return newTree;
5718 }
5719 function getNode(tree, path) {
5720 let currentNode = tree;
5721
5722 for (const branchName of path) {
5723 const nextNode = currentNode.children[branchName];
5724
5725 if (!nextNode) {
5726 return null;
5727 }
5728
5729 currentNode = nextNode;
5730 }
5731
5732 return currentNode;
5733 }
5734 function* iteratePath(tree, path) {
5735 let currentNode = tree;
5736 yield currentNode;
5737
5738 for (const branchName of path) {
5739 const nextNode = currentNode.children[branchName];
5740
5741 if (!nextNode) {
5742 break;
5743 }
5744
5745 yield nextNode;
5746 currentNode = nextNode;
5747 }
5748 }
5749 function* iterateDescendants(node) {
5750 const stack = Object.values(node.children);
5751
5752 while (stack.length) {
5753 const childNode = stack.pop();
5754 yield childNode;
5755 stack.push(...Object.values(childNode.children));
5756 }
5757 }
5758 function hasConflictingLock({
5759 exclusive
5760 }, locks) {
5761 if (exclusive && locks.length) {
5762 return true;
5763 }
5764
5765 if (!exclusive && locks.filter(lock => lock.exclusive).length) {
5766 return true;
5767 }
5768
5769 return false;
5770 }
5771
5772 ;// CONCATENATED MODULE: ./packages/core-data/build-module/locks/reducer.js
5773 /**
5774 * Internal dependencies
5775 */
5776
5777 const DEFAULT_STATE = {
5778 requests: [],
5779 tree: {
5780 locks: [],
5781 children: {}
5782 }
5783 };
5784 /**
5785 * Reducer returning locks.
5786 *
5787 * @param {Object} state Current state.
5788 * @param {Object} action Dispatched action.
5789 *
5790 * @return {Object} Updated state.
5791 */
5792
5793 function locks(state = DEFAULT_STATE, action) {
5794 switch (action.type) {
5795 case 'ENQUEUE_LOCK_REQUEST':
5796 {
5797 const {
5798 request
5799 } = action;
5800 return { ...state,
5801 requests: [request, ...state.requests]
5802 };
5803 }
5804
5805 case 'GRANT_LOCK_REQUEST':
5806 {
5807 const {
5808 lock,
5809 request
5810 } = action;
5811 const {
5812 store,
5813 path
5814 } = request;
5815 const storePath = [store, ...path];
5816 const newTree = deepCopyLocksTreePath(state.tree, storePath);
5817 const node = getNode(newTree, storePath);
5818 node.locks = [...node.locks, lock];
5819 return { ...state,
5820 requests: state.requests.filter(r => r !== request),
5821 tree: newTree
5822 };
5823 }
5824
5825 case 'RELEASE_LOCK':
5826 {
5827 const {
5828 lock
5829 } = action;
5830 const storePath = [lock.store, ...lock.path];
5831 const newTree = deepCopyLocksTreePath(state.tree, storePath);
5832 const node = getNode(newTree, storePath);
5833 node.locks = node.locks.filter(l => l !== lock);
5834 return { ...state,
5835 tree: newTree
5836 };
5837 }
5838 }
5839
5840 return state;
5841 }
5842
5843 ;// CONCATENATED MODULE: ./packages/core-data/build-module/locks/selectors.js
5844 /**
5845 * Internal dependencies
5846 */
5847
5848 function getPendingLockRequests(state) {
5849 return state.requests;
5850 }
5851 function isLockAvailable(state, store, path, {
5852 exclusive
5853 }) {
5854 const storePath = [store, ...path];
5855 const locks = state.tree; // Validate all parents and the node itself
5856
5857 for (const node of iteratePath(locks, storePath)) {
5858 if (hasConflictingLock({
5859 exclusive
5860 }, node.locks)) {
5861 return false;
5862 }
5863 } // iteratePath terminates early if path is unreachable, let's
5864 // re-fetch the node and check it exists in the tree.
5865
5866
5867 const node = getNode(locks, storePath);
5868
5869 if (!node) {
5870 return true;
5871 } // Validate all nested nodes
5872
5873
5874 for (const descendant of iterateDescendants(node)) {
5875 if (hasConflictingLock({
5876 exclusive
5877 }, descendant.locks)) {
5878 return false;
5879 }
5880 }
5881
5882 return true;
5883 }
5884
5885 ;// CONCATENATED MODULE: ./packages/core-data/build-module/locks/engine.js
5886 /**
5887 * Internal dependencies
5888 */
5889
5890
5891 function createLocks() {
5892 let state = locks(undefined, {
5893 type: '@@INIT'
5894 });
5895
5896 function processPendingLockRequests() {
5897 for (const request of getPendingLockRequests(state)) {
5898 const {
5899 store,
5900 path,
5901 exclusive,
5902 notifyAcquired
5903 } = request;
5904
5905 if (isLockAvailable(state, store, path, {
5906 exclusive
5907 })) {
5908 const lock = {
5909 store,
5910 path,
5911 exclusive
5912 };
5913 state = locks(state, {
5914 type: 'GRANT_LOCK_REQUEST',
5915 lock,
5916 request
5917 });
5918 notifyAcquired(lock);
5919 }
5920 }
5921 }
5922
5923 function acquire(store, path, exclusive) {
5924 return new Promise(resolve => {
5925 state = locks(state, {
5926 type: 'ENQUEUE_LOCK_REQUEST',
5927 request: {
5928 store,
5929 path,
5930 exclusive,
5931 notifyAcquired: resolve
5932 }
5933 });
5934 processPendingLockRequests();
5935 });
5936 }
5937
5938 function release(lock) {
5939 state = locks(state, {
5940 type: 'RELEASE_LOCK',
5941 lock
5942 });
5943 processPendingLockRequests();
5944 }
5945
5946 return {
5947 acquire,
5948 release
5949 };
5950 }
5951
5952 ;// CONCATENATED MODULE: ./packages/core-data/build-module/locks/actions.js
5953 /**
5954 * Internal dependencies
5955 */
5956
5957 function createLocksActions() {
5958 const locks = createLocks();
5959
5960 function __unstableAcquireStoreLock(store, path, {
5961 exclusive
5962 }) {
5963 return () => locks.acquire(store, path, exclusive);
5964 }
5965
5966 function __unstableReleaseStoreLock(lock) {
5967 return () => locks.release(lock);
5968 }
5969
5970 return {
5971 __unstableAcquireStoreLock,
5972 __unstableReleaseStoreLock
5973 };
5974 }
5975
5976 ;// CONCATENATED MODULE: external ["wp","privateApis"]
5977 const external_wp_privateApis_namespaceObject = window["wp"]["privateApis"];
5978 ;// CONCATENATED MODULE: ./packages/core-data/build-module/private-apis.js
5979 /**
5980 * WordPress dependencies
5981 */
5982
5983 const {
5984 lock,
5985 unlock
5986 } = (0,external_wp_privateApis_namespaceObject.__dangerousOptInToUnstableAPIsOnlyForCoreModules)('I know using unstable features means my plugin or theme will inevitably break on the next WordPress release.', '@wordpress/core-data');
5987
5988 ;// CONCATENATED MODULE: external ["wp","element"]
5989 const external_wp_element_namespaceObject = window["wp"]["element"];
5990 ;// CONCATENATED MODULE: external ["wp","blocks"]
5991 const external_wp_blocks_namespaceObject = window["wp"]["blocks"];
5992 ;// CONCATENATED MODULE: external ["wp","blockEditor"]
5993 const external_wp_blockEditor_namespaceObject = window["wp"]["blockEditor"];
5994 ;// CONCATENATED MODULE: ./packages/core-data/build-module/entity-provider.js
5995
5996
5997 /**
5998 * WordPress dependencies
5999 */
6000
6001
6002
6003
6004 /**
6005 * Internal dependencies
6006 */
6007
6008
6009
6010 /** @typedef {import('@wordpress/blocks').WPBlock} WPBlock */
6011
6012 const EMPTY_ARRAY = [];
6013 let oldFootnotes = {};
6014 /**
6015 * Internal dependencies
6016 */
6017
6018
6019 const entityContexts = { ...rootEntitiesConfig.reduce((acc, loader) => {
6020 if (!acc[loader.kind]) {
6021 acc[loader.kind] = {};
6022 }
6023
6024 acc[loader.kind][loader.name] = {
6025 context: (0,external_wp_element_namespaceObject.createContext)(undefined)
6026 };
6027 return acc;
6028 }, {}),
6029 ...additionalEntityConfigLoaders.reduce((acc, loader) => {
6030 acc[loader.kind] = {};
6031 return acc;
6032 }, {})
6033 };
6034
6035 const getEntityContext = (kind, name) => {
6036 if (!entityContexts[kind]) {
6037 throw new Error(`Missing entity config for kind: ${kind}.`);
6038 }
6039
6040 if (!entityContexts[kind][name]) {
6041 entityContexts[kind][name] = {
6042 context: (0,external_wp_element_namespaceObject.createContext)(undefined)
6043 };
6044 }
6045
6046 return entityContexts[kind][name].context;
6047 };
6048 /**
6049 * Context provider component for providing
6050 * an entity for a specific entity.
6051 *
6052 * @param {Object} props The component's props.
6053 * @param {string} props.kind The entity kind.
6054 * @param {string} props.type The entity name.
6055 * @param {number} props.id The entity ID.
6056 * @param {*} props.children The children to wrap.
6057 *
6058 * @return {Object} The provided children, wrapped with
6059 * the entity's context provider.
6060 */
6061
6062
6063 function EntityProvider({
6064 kind,
6065 type: name,
6066 id,
6067 children
6068 }) {
6069 const Provider = getEntityContext(kind, name).Provider;
6070 return (0,external_wp_element_namespaceObject.createElement)(Provider, {
6071 value: id
6072 }, children);
6073 }
6074 /**
6075 * Hook that returns the ID for the nearest
6076 * provided entity of the specified type.
6077 *
6078 * @param {string} kind The entity kind.
6079 * @param {string} name The entity name.
6080 */
6081
6082 function useEntityId(kind, name) {
6083 return (0,external_wp_element_namespaceObject.useContext)(getEntityContext(kind, name));
6084 }
6085 /**
6086 * Hook that returns the value and a setter for the
6087 * specified property of the nearest provided
6088 * entity of the specified type.
6089 *
6090 * @param {string} kind The entity kind.
6091 * @param {string} name The entity name.
6092 * @param {string} prop The property name.
6093 * @param {string} [_id] An entity ID to use instead of the context-provided one.
6094 *
6095 * @return {[*, Function, *]} An array where the first item is the
6096 * property value, the second is the
6097 * setter and the third is the full value
6098 * object from REST API containing more
6099 * information like `raw`, `rendered` and
6100 * `protected` props.
6101 */
6102
6103 function useEntityProp(kind, name, prop, _id) {
6104 const providerId = useEntityId(kind, name);
6105 const id = _id !== null && _id !== void 0 ? _id : providerId;
6106 const {
6107 value,
6108 fullValue
6109 } = (0,external_wp_data_namespaceObject.useSelect)(select => {
6110 const {
6111 getEntityRecord,
6112 getEditedEntityRecord
6113 } = select(STORE_NAME);
6114 const record = getEntityRecord(kind, name, id); // Trigger resolver.
6115
6116 const editedRecord = getEditedEntityRecord(kind, name, id);
6117 return record && editedRecord ? {
6118 value: editedRecord[prop],
6119 fullValue: record[prop]
6120 } : {};
6121 }, [kind, name, id, prop]);
6122 const {
6123 editEntityRecord
6124 } = (0,external_wp_data_namespaceObject.useDispatch)(STORE_NAME);
6125 const setValue = (0,external_wp_element_namespaceObject.useCallback)(newValue => {
6126 editEntityRecord(kind, name, id, {
6127 [prop]: newValue
6128 });
6129 }, [kind, name, id, prop]);
6130 return [value, setValue, fullValue];
6131 }
6132 /**
6133 * Hook that returns block content getters and setters for
6134 * the nearest provided entity of the specified type.
6135 *
6136 * The return value has the shape `[ blocks, onInput, onChange ]`.
6137 * `onInput` is for block changes that don't create undo levels
6138 * or dirty the post, non-persistent changes, and `onChange` is for
6139 * peristent changes. They map directly to the props of a
6140 * `BlockEditorProvider` and are intended to be used with it,
6141 * or similar components or hooks.
6142 *
6143 * @param {string} kind The entity kind.
6144 * @param {string} name The entity name.
6145 * @param {Object} options
6146 * @param {string} [options.id] An entity ID to use instead of the context-provided one.
6147 *
6148 * @return {[WPBlock[], Function, Function]} The block array and setters.
6149 */
6150
6151 function useEntityBlockEditor(kind, name, {
6152 id: _id
6153 } = {}) {
6154 const providerId = useEntityId(kind, name);
6155 const id = _id !== null && _id !== void 0 ? _id : providerId;
6156 const {
6157 content,
6158 blocks,
6159 meta
6160 } = (0,external_wp_data_namespaceObject.useSelect)(select => {
6161 const {
6162 getEditedEntityRecord
6163 } = select(STORE_NAME);
6164 const editedRecord = getEditedEntityRecord(kind, name, id);
6165 return {
6166 blocks: editedRecord.blocks,
6167 content: editedRecord.content,
6168 meta: editedRecord.meta
6169 };
6170 }, [kind, name, id]);
6171 const {
6172 __unstableCreateUndoLevel,
6173 editEntityRecord
6174 } = (0,external_wp_data_namespaceObject.useDispatch)(STORE_NAME);
6175 (0,external_wp_element_namespaceObject.useEffect)(() => {
6176 // Load the blocks from the content if not already in state
6177 // Guard against other instances that might have
6178 // set content to a function already or the blocks are already in state.
6179 if (content && typeof content !== 'function' && !blocks) {
6180 const parsedContent = (0,external_wp_blocks_namespaceObject.parse)(content);
6181 editEntityRecord(kind, name, id, {
6182 blocks: parsedContent
6183 }, {
6184 undoIgnore: true
6185 });
6186 }
6187 }, [content]);
6188 const updateFootnotes = (0,external_wp_element_namespaceObject.useCallback)(_blocks => {
6189 const output = {
6190 blocks: _blocks
6191 };
6192 if (!meta) return output; // If meta.footnotes is empty, it means the meta is not registered.
6193
6194 if (meta.footnotes === undefined) return output;
6195 const {
6196 getRichTextValues
6197 } = unlock(external_wp_blockEditor_namespaceObject.privateApis);
6198
6199 const _content = getRichTextValues(_blocks).join('') || '';
6200
6201 const newOrder = []; // This can be avoided when
6202 // https://github.com/WordPress/gutenberg/pull/43204 lands. We can then
6203 // get the order directly from the rich text values.
6204
6205 if (_content.indexOf('data-fn') !== -1) {
6206 const regex = /data-fn="([^"]+)"/g;
6207 let match;
6208
6209 while ((match = regex.exec(_content)) !== null) {
6210 newOrder.push(match[1]);
6211 }
6212 }
6213
6214 const footnotes = meta.footnotes ? JSON.parse(meta.footnotes) : [];
6215 const currentOrder = footnotes.map(fn => fn.id);
6216 if (currentOrder.join('') === newOrder.join('')) return output;
6217 const newFootnotes = newOrder.map(fnId => footnotes.find(fn => fn.id === fnId) || oldFootnotes[fnId] || {
6218 id: fnId,
6219 content: ''
6220 });
6221
6222 function updateAttributes(attributes) {
6223 attributes = { ...attributes
6224 };
6225
6226 for (const key in attributes) {
6227 const value = attributes[key];
6228
6229 if (Array.isArray(value)) {
6230 attributes[key] = value.map(updateAttributes);
6231 continue;
6232 }
6233
6234 if (typeof value !== 'string') {
6235 continue;
6236 }
6237
6238 if (value.indexOf('data-fn') === -1) {
6239 continue;
6240 } // When we store rich text values, this would no longer
6241 // require a regex.
6242
6243
6244 const regex = /(<sup[^>]+data-fn="([^"]+)"[^>]*><a[^>]*>)[\d*]*<\/a><\/sup>/g;
6245 attributes[key] = value.replace(regex, (match, opening, fnId) => {
6246 const index = newOrder.indexOf(fnId);
6247 return `${opening}${index + 1}</a></sup>`;
6248 });
6249 const compatRegex = /<a[^>]+data-fn="([^"]+)"[^>]*>\*<\/a>/g;
6250 attributes[key] = attributes[key].replace(compatRegex, (match, fnId) => {
6251 const index = newOrder.indexOf(fnId);
6252 return `<sup data-fn="${fnId}" class="fn"><a href="#${fnId}" id="${fnId}-link">${index + 1}</a></sup>`;
6253 });
6254 }
6255
6256 return attributes;
6257 }
6258
6259 function updateBlocksAttributes(__blocks) {
6260 return __blocks.map(block => {
6261 return { ...block,
6262 attributes: updateAttributes(block.attributes),
6263 innerBlocks: updateBlocksAttributes(block.innerBlocks)
6264 };
6265 });
6266 } // We need to go through all block attributs deeply and update the
6267 // footnote anchor numbering (textContent) to match the new order.
6268
6269
6270 const newBlocks = updateBlocksAttributes(_blocks);
6271 oldFootnotes = { ...oldFootnotes,
6272 ...footnotes.reduce((acc, fn) => {
6273 if (!newOrder.includes(fn.id)) {
6274 acc[fn.id] = fn;
6275 }
6276
6277 return acc;
6278 }, {})
6279 };
6280 return {
6281 meta: { ...meta,
6282 footnotes: JSON.stringify(newFootnotes)
6283 },
6284 blocks: newBlocks
6285 };
6286 }, [meta]);
6287 const onChange = (0,external_wp_element_namespaceObject.useCallback)((newBlocks, options) => {
6288 const noChange = blocks === newBlocks;
6289
6290 if (noChange) {
6291 return __unstableCreateUndoLevel(kind, name, id);
6292 }
6293
6294 const {
6295 selection
6296 } = options; // We create a new function here on every persistent edit
6297 // to make sure the edit makes the post dirty and creates
6298 // a new undo level.
6299
6300 const edits = {
6301 selection,
6302 content: ({
6303 blocks: blocksForSerialization = []
6304 }) => (0,external_wp_blocks_namespaceObject.__unstableSerializeAndClean)(blocksForSerialization),
6305 ...updateFootnotes(newBlocks)
6306 };
6307 editEntityRecord(kind, name, id, edits, {
6308 isCached: false
6309 });
6310 }, [kind, name, id, blocks, updateFootnotes, __unstableCreateUndoLevel, editEntityRecord]);
6311 const onInput = (0,external_wp_element_namespaceObject.useCallback)((newBlocks, options) => {
6312 const {
6313 selection
6314 } = options;
6315 const footnotesChanges = updateFootnotes(newBlocks);
6316 const edits = {
6317 selection,
6318 ...footnotesChanges
6319 };
6320 editEntityRecord(kind, name, id, edits, {
6321 isCached: true
6322 });
6323 }, [kind, name, id, updateFootnotes, editEntityRecord]);
6324 return [blocks !== null && blocks !== void 0 ? blocks : EMPTY_ARRAY, onInput, onChange];
6325 }
6326
6327 ;// CONCATENATED MODULE: external ["wp","htmlEntities"]
6328 const external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"];
6329 ;// CONCATENATED MODULE: ./packages/core-data/build-module/fetch/__experimental-fetch-link-suggestions.js
6330 /**
6331 * WordPress dependencies
6332 */
6333
6334
6335
6336
6337 /**
6338 * Filters the search by type
6339 *
6340 * @typedef { 'attachment' | 'post' | 'term' | 'post-format' } WPLinkSearchType
6341 */
6342
6343 /**
6344 * A link with an id may be of kind post-type or taxonomy
6345 *
6346 * @typedef { 'post-type' | 'taxonomy' } WPKind
6347 */
6348
6349 /**
6350 * @typedef WPLinkSearchOptions
6351 *
6352 * @property {boolean} [isInitialSuggestions] Displays initial search suggestions, when true.
6353 * @property {WPLinkSearchType} [type] Filters by search type.
6354 * @property {string} [subtype] Slug of the post-type or taxonomy.
6355 * @property {number} [page] Which page of results to return.
6356 * @property {number} [perPage] Search results per page.
6357 */
6358
6359 /**
6360 * @typedef WPLinkSearchResult
6361 *
6362 * @property {number} id Post or term id.
6363 * @property {string} url Link url.
6364 * @property {string} title Title of the link.
6365 * @property {string} type The taxonomy or post type slug or type URL.
6366 * @property {WPKind} [kind] Link kind of post-type or taxonomy
6367 */
6368
6369 /**
6370 * @typedef WPLinkSearchResultAugments
6371 *
6372 * @property {{kind: WPKind}} [meta] Contains kind information.
6373 * @property {WPKind} [subtype] Optional subtype if it exists.
6374 */
6375
6376 /**
6377 * @typedef {WPLinkSearchResult & WPLinkSearchResultAugments} WPLinkSearchResultAugmented
6378 */
6379
6380 /**
6381 * @typedef WPEditorSettings
6382 *
6383 * @property {boolean} [ disablePostFormats ] Disables post formats, when true.
6384 */
6385
6386 /**
6387 * Fetches link suggestions from the API.
6388 *
6389 * @async
6390 * @param {string} search
6391 * @param {WPLinkSearchOptions} [searchOptions]
6392 * @param {WPEditorSettings} [settings]
6393 *
6394 * @example
6395 * ```js
6396 * import { __experimentalFetchLinkSuggestions as fetchLinkSuggestions } from '@wordpress/core-data';
6397 *
6398 * //...
6399 *
6400 * export function initialize( id, settings ) {
6401 *
6402 * settings.__experimentalFetchLinkSuggestions = (
6403 * search,
6404 * searchOptions
6405 * ) => fetchLinkSuggestions( search, searchOptions, settings );
6406 * ```
6407 * @return {Promise< WPLinkSearchResult[] >} List of search suggestions
6408 */
6409
6410 const fetchLinkSuggestions = async (search, searchOptions = {}, settings = {}) => {
6411 const {
6412 isInitialSuggestions = false,
6413 type = undefined,
6414 subtype = undefined,
6415 page = undefined,
6416 perPage = isInitialSuggestions ? 3 : 20
6417 } = searchOptions;
6418 const {
6419 disablePostFormats = false
6420 } = settings;
6421 /** @type {Promise<WPLinkSearchResult>[]} */
6422
6423 const queries = [];
6424
6425 if (!type || type === 'post') {
6426 queries.push(external_wp_apiFetch_default()({
6427 path: (0,external_wp_url_namespaceObject.addQueryArgs)('/wp/v2/search', {
6428 search,
6429 page,
6430 per_page: perPage,
6431 type: 'post',
6432 subtype
6433 })
6434 }).then(results => {
6435 return results.map(result => {
6436 return { ...result,
6437 meta: {
6438 kind: 'post-type',
6439 subtype
6440 }
6441 };
6442 });
6443 }).catch(() => []) // Fail by returning no results.
6444 );
6445 }
6446
6447 if (!type || type === 'term') {
6448 queries.push(external_wp_apiFetch_default()({
6449 path: (0,external_wp_url_namespaceObject.addQueryArgs)('/wp/v2/search', {
6450 search,
6451 page,
6452 per_page: perPage,
6453 type: 'term',
6454 subtype
6455 })
6456 }).then(results => {
6457 return results.map(result => {
6458 return { ...result,
6459 meta: {
6460 kind: 'taxonomy',
6461 subtype
6462 }
6463 };
6464 });
6465 }).catch(() => []) // Fail by returning no results.
6466 );
6467 }
6468
6469 if (!disablePostFormats && (!type || type === 'post-format')) {
6470 queries.push(external_wp_apiFetch_default()({
6471 path: (0,external_wp_url_namespaceObject.addQueryArgs)('/wp/v2/search', {
6472 search,
6473 page,
6474 per_page: perPage,
6475 type: 'post-format',
6476 subtype
6477 })
6478 }).then(results => {
6479 return results.map(result => {
6480 return { ...result,
6481 meta: {
6482 kind: 'taxonomy',
6483 subtype
6484 }
6485 };
6486 });
6487 }).catch(() => []) // Fail by returning no results.
6488 );
6489 }
6490
6491 if (!type || type === 'attachment') {
6492 queries.push(external_wp_apiFetch_default()({
6493 path: (0,external_wp_url_namespaceObject.addQueryArgs)('/wp/v2/media', {
6494 search,
6495 page,
6496 per_page: perPage
6497 })
6498 }).then(results => {
6499 return results.map(result => {
6500 return { ...result,
6501 meta: {
6502 kind: 'media'
6503 }
6504 };
6505 });
6506 }).catch(() => []) // Fail by returning no results.
6507 );
6508 }
6509
6510 return Promise.all(queries).then(results => {
6511 return results.reduce((
6512 /** @type {WPLinkSearchResult[]} */
6513 accumulator, current) => accumulator.concat(current), // Flatten list.
6514 []).filter(
6515 /**
6516 * @param {{ id: number }} result
6517 */
6518 result => {
6519 return !!result.id;
6520 }).slice(0, perPage).map((
6521 /** @type {WPLinkSearchResultAugmented} */
6522 result) => {
6523 const isMedia = result.type === 'attachment';
6524 return {
6525 id: result.id,
6526 // @ts-ignore fix when we make this a TS file
6527 url: isMedia ? result.source_url : result.url,
6528 title: (0,external_wp_htmlEntities_namespaceObject.decodeEntities)(isMedia ? // @ts-ignore fix when we make this a TS file
6529 result.title.rendered : result.title || '') || (0,external_wp_i18n_namespaceObject.__)('(no title)'),
6530 type: result.subtype || result.type,
6531 kind: result?.meta?.kind
6532 };
6533 });
6534 });
6535 };
6536
6537 /* harmony default export */ const _experimental_fetch_link_suggestions = (fetchLinkSuggestions);
6538
6539 ;// CONCATENATED MODULE: ./packages/core-data/build-module/fetch/__experimental-fetch-url-data.js
6540 /**
6541 * WordPress dependencies
6542 */
6543
6544
6545 /**
6546 * A simple in-memory cache for requests.
6547 * This avoids repeat HTTP requests which may be beneficial
6548 * for those wishing to preserve low-bandwidth.
6549 */
6550
6551 const CACHE = new Map();
6552 /**
6553 * @typedef WPRemoteUrlData
6554 *
6555 * @property {string} title contents of the remote URL's `<title>` tag.
6556 */
6557
6558 /**
6559 * Fetches data about a remote URL.
6560 * eg: <title> tag, favicon...etc.
6561 *
6562 * @async
6563 * @param {string} url the URL to request details from.
6564 * @param {Object?} options any options to pass to the underlying fetch.
6565 * @example
6566 * ```js
6567 * import { __experimentalFetchUrlData as fetchUrlData } from '@wordpress/core-data';
6568 *
6569 * //...
6570 *
6571 * export function initialize( id, settings ) {
6572 *
6573 * settings.__experimentalFetchUrlData = (
6574 * url
6575 * ) => fetchUrlData( url );
6576 * ```
6577 * @return {Promise< WPRemoteUrlData[] >} Remote URL data.
6578 */
6579
6580 const fetchUrlData = async (url, options = {}) => {
6581 const endpoint = '/wp-block-editor/v1/url-details';
6582 const args = {
6583 url: (0,external_wp_url_namespaceObject.prependHTTP)(url)
6584 };
6585
6586 if (!(0,external_wp_url_namespaceObject.isURL)(url)) {
6587 return Promise.reject(`${url} is not a valid URL.`);
6588 } // Test for "http" based URL as it is possible for valid
6589 // yet unusable URLs such as `tel:123456` to be passed.
6590
6591
6592 const protocol = (0,external_wp_url_namespaceObject.getProtocol)(url);
6593
6594 if (!protocol || !(0,external_wp_url_namespaceObject.isValidProtocol)(protocol) || !protocol.startsWith('http') || !/^https?:\/\/[^\/\s]/i.test(url)) {
6595 return Promise.reject(`${url} does not have a valid protocol. URLs must be "http" based`);
6596 }
6597
6598 if (CACHE.has(url)) {
6599 return CACHE.get(url);
6600 }
6601
6602 return external_wp_apiFetch_default()({
6603 path: (0,external_wp_url_namespaceObject.addQueryArgs)(endpoint, args),
6604 ...options
6605 }).then(res => {
6606 CACHE.set(url, res);
6607 return res;
6608 });
6609 };
6610
6611 /* harmony default export */ const _experimental_fetch_url_data = (fetchUrlData);
6612
6613 ;// CONCATENATED MODULE: ./packages/core-data/build-module/fetch/index.js
6614
6615
6616
6617 ;// CONCATENATED MODULE: ./node_modules/memize/dist/index.js
6618 /**
6619 * Memize options object.
6620 *
6621 * @typedef MemizeOptions
6622 *
6623 * @property {number} [maxSize] Maximum size of the cache.
6624 */
6625
6626 /**
6627 * Internal cache entry.
6628 *
6629 * @typedef MemizeCacheNode
6630 *
6631 * @property {?MemizeCacheNode|undefined} [prev] Previous node.
6632 * @property {?MemizeCacheNode|undefined} [next] Next node.
6633 * @property {Array<*>} args Function arguments for cache
6634 * entry.
6635 * @property {*} val Function result.
6636 */
6637
6638 /**
6639 * Properties of the enhanced function for controlling cache.
6640 *
6641 * @typedef MemizeMemoizedFunction
6642 *
6643 * @property {()=>void} clear Clear the cache.
6644 */
6645
6646 /**
6647 * Accepts a function to be memoized, and returns a new memoized function, with
6648 * optional options.
6649 *
6650 * @template {(...args: any[]) => any} F
6651 *
6652 * @param {F} fn Function to memoize.
6653 * @param {MemizeOptions} [options] Options object.
6654 *
6655 * @return {((...args: Parameters<F>) => ReturnType<F>) & MemizeMemoizedFunction} Memoized function.
6656 */
6657 function memize(fn, options) {
6658 var size = 0;
6659
6660 /** @type {?MemizeCacheNode|undefined} */
6661 var head;
6662
6663 /** @type {?MemizeCacheNode|undefined} */
6664 var tail;
6665
6666 options = options || {};
6667
6668 function memoized(/* ...args */) {
6669 var node = head,
6670 len = arguments.length,
6671 args,
6672 i;
6673
6674 searchCache: while (node) {
6675 // Perform a shallow equality test to confirm that whether the node
6676 // under test is a candidate for the arguments passed. Two arrays
6677 // are shallowly equal if their length matches and each entry is
6678 // strictly equal between the two sets. Avoid abstracting to a
6679 // function which could incur an arguments leaking deoptimization.
6680
6681 // Check whether node arguments match arguments length
6682 if (node.args.length !== arguments.length) {
6683 node = node.next;
6684 continue;
6685 }
6686
6687 // Check whether node arguments match arguments values
6688 for (i = 0; i < len; i++) {
6689 if (node.args[i] !== arguments[i]) {
6690 node = node.next;
6691 continue searchCache;
6692 }
6693 }
6694
6695 // At this point we can assume we've found a match
6696
6697 // Surface matched node to head if not already
6698 if (node !== head) {
6699 // As tail, shift to previous. Must only shift if not also
6700 // head, since if both head and tail, there is no previous.
6701 if (node === tail) {
6702 tail = node.prev;
6703 }
6704
6705 // Adjust siblings to point to each other. If node was tail,
6706 // this also handles new tail's empty `next` assignment.
6707 /** @type {MemizeCacheNode} */ (node.prev).next = node.next;
6708 if (node.next) {
6709 node.next.prev = node.prev;
6710 }
6711
6712 node.next = head;
6713 node.prev = null;
6714 /** @type {MemizeCacheNode} */ (head).prev = node;
6715 head = node;
6716 }
6717
6718 // Return immediately
6719 return node.val;
6720 }
6721
6722 // No cached value found. Continue to insertion phase:
6723
6724 // Create a copy of arguments (avoid leaking deoptimization)
6725 args = new Array(len);
6726 for (i = 0; i < len; i++) {
6727 args[i] = arguments[i];
6728 }
6729
6730 node = {
6731 args: args,
6732
6733 // Generate the result from original function
6734 val: fn.apply(null, args),
6735 };
6736
6737 // Don't need to check whether node is already head, since it would
6738 // have been returned above already if it was
6739
6740 // Shift existing head down list
6741 if (head) {
6742 head.prev = node;
6743 node.next = head;
6744 } else {
6745 // If no head, follows that there's no tail (at initial or reset)
6746 tail = node;
6747 }
6748
6749 // Trim tail if we're reached max size and are pending cache insertion
6750 if (size === /** @type {MemizeOptions} */ (options).maxSize) {
6751 tail = /** @type {MemizeCacheNode} */ (tail).prev;
6752 /** @type {MemizeCacheNode} */ (tail).next = null;
6753 } else {
6754 size++;
6755 }
6756
6757 head = node;
6758
6759 return node.val;
6760 }
6761
6762 memoized.clear = function () {
6763 head = null;
6764 tail = null;
6765 size = 0;
6766 };
6767
6768 // Ignore reason: There's not a clear solution to create an intersection of
6769 // the function with additional properties, where the goal is to retain the
6770 // function signature of the incoming argument and add control properties
6771 // on the return value.
6772
6773 // @ts-ignore
6774 return memoized;
6775 }
6776
6777
6778
6779 ;// CONCATENATED MODULE: ./packages/core-data/build-module/hooks/memoize.js
6780 /**
6781 * External dependencies
6782 */
6783 // re-export due to restrictive esModuleInterop setting
6784
6785 /* harmony default export */ const memoize = (memize);
6786
6787 ;// CONCATENATED MODULE: ./packages/core-data/build-module/hooks/constants.js
6788 let Status;
6789
6790 (function (Status) {
6791 Status["Idle"] = "IDLE";
6792 Status["Resolving"] = "RESOLVING";
6793 Status["Error"] = "ERROR";
6794 Status["Success"] = "SUCCESS";
6795 })(Status || (Status = {}));
6796
6797 ;// CONCATENATED MODULE: ./packages/core-data/build-module/hooks/use-query-select.js
6798 /**
6799 * WordPress dependencies
6800 */
6801
6802 /**
6803 * Internal dependencies
6804 */
6805
6806
6807
6808 const META_SELECTORS = ['getIsResolving', 'hasStartedResolution', 'hasFinishedResolution', 'isResolving', 'getCachedResolvers'];
6809
6810 /**
6811 * Like useSelect, but the selectors return objects containing
6812 * both the original data AND the resolution info.
6813 *
6814 * @since 6.1.0 Introduced in WordPress core.
6815 * @private
6816 *
6817 * @param {Function} mapQuerySelect see useSelect
6818 * @param {Array} deps see useSelect
6819 *
6820 * @example
6821 * ```js
6822 * import { useQuerySelect } from '@wordpress/data';
6823 * import { store as coreDataStore } from '@wordpress/core-data';
6824 *
6825 * function PageTitleDisplay( { id } ) {
6826 * const { data: page, isResolving } = useQuerySelect( ( query ) => {
6827 * return query( coreDataStore ).getEntityRecord( 'postType', 'page', id )
6828 * }, [ id ] );
6829 *
6830 * if ( isResolving ) {
6831 * return 'Loading...';
6832 * }
6833 *
6834 * return page.title;
6835 * }
6836 *
6837 * // Rendered in the application:
6838 * // <PageTitleDisplay id={ 10 } />
6839 * ```
6840 *
6841 * In the above example, when `PageTitleDisplay` is rendered into an
6842 * application, the page and the resolution details will be retrieved from
6843 * the store state using the `mapSelect` callback on `useQuerySelect`.
6844 *
6845 * If the id prop changes then any page in the state for that id is
6846 * retrieved. If the id prop doesn't change and other props are passed in
6847 * that do change, the title will not change because the dependency is just
6848 * the id.
6849 * @see useSelect
6850 *
6851 * @return {QuerySelectResponse} Queried data.
6852 */
6853 function useQuerySelect(mapQuerySelect, deps) {
6854 return (0,external_wp_data_namespaceObject.useSelect)((select, registry) => {
6855 const resolve = store => enrichSelectors(select(store));
6856
6857 return mapQuerySelect(resolve, registry);
6858 }, deps);
6859 }
6860
6861 /**
6862 * Transform simple selectors into ones that return an object with the
6863 * original return value AND the resolution info.
6864 *
6865 * @param {Object} selectors Selectors to enrich
6866 * @return {EnrichedSelectors} Enriched selectors
6867 */
6868 const enrichSelectors = memoize(selectors => {
6869 const resolvers = {};
6870
6871 for (const selectorName in selectors) {
6872 if (META_SELECTORS.includes(selectorName)) {
6873 continue;
6874 }
6875
6876 Object.defineProperty(resolvers, selectorName, {
6877 get: () => (...args) => {
6878 const {
6879 getIsResolving,
6880 hasFinishedResolution
6881 } = selectors;
6882 const isResolving = !!getIsResolving(selectorName, args);
6883 const hasResolved = !isResolving && hasFinishedResolution(selectorName, args);
6884 const data = selectors[selectorName](...args);
6885 let status;
6886
6887 if (isResolving) {
6888 status = Status.Resolving;
6889 } else if (hasResolved) {
6890 if (data) {
6891 status = Status.Success;
6892 } else {
6893 status = Status.Error;
6894 }
6895 } else {
6896 status = Status.Idle;
6897 }
6898
6899 return {
6900 data,
6901 status,
6902 isResolving,
6903 hasResolved
6904 };
6905 }
6906 });
6907 }
6908
6909 return resolvers;
6910 });
6911
6912 ;// CONCATENATED MODULE: ./packages/core-data/build-module/hooks/use-entity-record.js
6913 /**
6914 * WordPress dependencies
6915 */
6916
6917
6918
6919 /**
6920 * Internal dependencies
6921 */
6922
6923
6924
6925
6926 /**
6927 * Resolves the specified entity record.
6928 *
6929 * @since 6.1.0 Introduced in WordPress core.
6930 *
6931 * @param kind Kind of the entity, e.g. `root` or a `postType`. See rootEntitiesConfig in ../entities.ts for a list of available kinds.
6932 * @param name Name of the entity, e.g. `plugin` or a `post`. See rootEntitiesConfig in ../entities.ts for a list of available names.
6933 * @param recordId ID of the requested entity record.
6934 * @param options Optional hook options.
6935 * @example
6936 * ```js
6937 * import { useEntityRecord } from '@wordpress/core-data';
6938 *
6939 * function PageTitleDisplay( { id } ) {
6940 * const { record, isResolving } = useEntityRecord( 'postType', 'page', id );
6941 *
6942 * if ( isResolving ) {
6943 * return 'Loading...';
6944 * }
6945 *
6946 * return record.title;
6947 * }
6948 *
6949 * // Rendered in the application:
6950 * // <PageTitleDisplay id={ 1 } />
6951 * ```
6952 *
6953 * In the above example, when `PageTitleDisplay` is rendered into an
6954 * application, the page and the resolution details will be retrieved from
6955 * the store state using `getEntityRecord()`, or resolved if missing.
6956 *
6957 * @example
6958 * ```js
6959 * import { useDispatch } from '@wordpress/data';
6960 * import { useCallback } from '@wordpress/element';
6961 * import { __ } from '@wordpress/i18n';
6962 * import { TextControl } from '@wordpress/components';
6963 * import { store as noticeStore } from '@wordpress/notices';
6964 * import { useEntityRecord } from '@wordpress/core-data';
6965 *
6966 * function PageRenameForm( { id } ) {
6967 * const page = useEntityRecord( 'postType', 'page', id );
6968 * const { createSuccessNotice, createErrorNotice } =
6969 * useDispatch( noticeStore );
6970 *
6971 * const setTitle = useCallback( ( title ) => {
6972 * page.edit( { title } );
6973 * }, [ page.edit ] );
6974 *
6975 * if ( page.isResolving ) {
6976 * return 'Loading...';
6977 * }
6978 *
6979 * async function onRename( event ) {
6980 * event.preventDefault();
6981 * try {
6982 * await page.save();
6983 * createSuccessNotice( __( 'Page renamed.' ), {
6984 * type: 'snackbar',
6985 * } );
6986 * } catch ( error ) {
6987 * createErrorNotice( error.message, { type: 'snackbar' } );
6988 * }
6989 * }
6990 *
6991 * return (
6992 * <form onSubmit={ onRename }>
6993 * <TextControl
6994 * label={ __( 'Name' ) }
6995 * value={ page.editedRecord.title }
6996 * onChange={ setTitle }
6997 * />
6998 * <button type="submit">{ __( 'Save' ) }</button>
6999 * </form>
7000 * );
7001 * }
7002 *
7003 * // Rendered in the application:
7004 * // <PageRenameForm id={ 1 } />
7005 * ```
7006 *
7007 * In the above example, updating and saving the page title is handled
7008 * via the `edit()` and `save()` mutation helpers provided by
7009 * `useEntityRecord()`;
7010 *
7011 * @return Entity record data.
7012 * @template RecordType
7013 */
7014 function useEntityRecord(kind, name, recordId, options = {
7015 enabled: true
7016 }) {
7017 const {
7018 editEntityRecord,
7019 saveEditedEntityRecord
7020 } = (0,external_wp_data_namespaceObject.useDispatch)(store);
7021 const mutations = (0,external_wp_element_namespaceObject.useMemo)(() => ({
7022 edit: record => editEntityRecord(kind, name, recordId, record),
7023 save: (saveOptions = {}) => saveEditedEntityRecord(kind, name, recordId, {
7024 throwOnError: true,
7025 ...saveOptions
7026 })
7027 }), [editEntityRecord, kind, name, recordId, saveEditedEntityRecord]);
7028 const {
7029 editedRecord,
7030 hasEdits
7031 } = (0,external_wp_data_namespaceObject.useSelect)(select => ({
7032 editedRecord: select(store).getEditedEntityRecord(kind, name, recordId),
7033 hasEdits: select(store).hasEditsForEntityRecord(kind, name, recordId)
7034 }), [kind, name, recordId]);
7035 const {
7036 data: record,
7037 ...querySelectRest
7038 } = useQuerySelect(query => {
7039 if (!options.enabled) {
7040 return {
7041 data: null
7042 };
7043 }
7044
7045 return query(store).getEntityRecord(kind, name, recordId);
7046 }, [kind, name, recordId, options.enabled]);
7047 return {
7048 record,
7049 editedRecord,
7050 hasEdits,
7051 ...querySelectRest,
7052 ...mutations
7053 };
7054 }
7055 function __experimentalUseEntityRecord(kind, name, recordId, options) {
7056 external_wp_deprecated_default()(`wp.data.__experimentalUseEntityRecord`, {
7057 alternative: 'wp.data.useEntityRecord',
7058 since: '6.1'
7059 });
7060 return useEntityRecord(kind, name, recordId, options);
7061 }
7062
7063 ;// CONCATENATED MODULE: ./packages/core-data/build-module/hooks/use-entity-records.js
7064 /**
7065 * WordPress dependencies
7066 */
7067
7068
7069 /**
7070 * Internal dependencies
7071 */
7072
7073
7074
7075 const use_entity_records_EMPTY_ARRAY = [];
7076 /**
7077 * Resolves the specified entity records.
7078 *
7079 * @since 6.1.0 Introduced in WordPress core.
7080 *
7081 * @param kind Kind of the entity, e.g. `root` or a `postType`. See rootEntitiesConfig in ../entities.ts for a list of available kinds.
7082 * @param name Name of the entity, e.g. `plugin` or a `post`. See rootEntitiesConfig in ../entities.ts for a list of available names.
7083 * @param queryArgs Optional HTTP query description for how to fetch the data, passed to the requested API endpoint.
7084 * @param options Optional hook options.
7085 * @example
7086 * ```js
7087 * import { useEntityRecords } from '@wordpress/core-data';
7088 *
7089 * function PageTitlesList() {
7090 * const { records, isResolving } = useEntityRecords( 'postType', 'page' );
7091 *
7092 * if ( isResolving ) {
7093 * return 'Loading...';
7094 * }
7095 *
7096 * return (
7097 * <ul>
7098 * {records.map(( page ) => (
7099 * <li>{ page.title }</li>
7100 * ))}
7101 * </ul>
7102 * );
7103 * }
7104 *
7105 * // Rendered in the application:
7106 * // <PageTitlesList />
7107 * ```
7108 *
7109 * In the above example, when `PageTitlesList` is rendered into an
7110 * application, the list of records and the resolution details will be retrieved from
7111 * the store state using `getEntityRecords()`, or resolved if missing.
7112 *
7113 * @return Entity records data.
7114 * @template RecordType
7115 */
7116
7117 function useEntityRecords(kind, name, queryArgs = {}, options = {
7118 enabled: true
7119 }) {
7120 // Serialize queryArgs to a string that can be safely used as a React dep.
7121 // We can't just pass queryArgs as one of the deps, because if it is passed
7122 // as an object literal, then it will be a different object on each call even
7123 // if the values remain the same.
7124 const queryAsString = (0,external_wp_url_namespaceObject.addQueryArgs)('', queryArgs);
7125 const {
7126 data: records,
7127 ...rest
7128 } = useQuerySelect(query => {
7129 if (!options.enabled) {
7130 return {
7131 // Avoiding returning a new reference on every execution.
7132 data: use_entity_records_EMPTY_ARRAY
7133 };
7134 }
7135
7136 return query(store).getEntityRecords(kind, name, queryArgs);
7137 }, [kind, name, queryAsString, options.enabled]);
7138 return {
7139 records,
7140 ...rest
7141 };
7142 }
7143 function __experimentalUseEntityRecords(kind, name, queryArgs, options) {
7144 external_wp_deprecated_default()(`wp.data.__experimentalUseEntityRecords`, {
7145 alternative: 'wp.data.useEntityRecords',
7146 since: '6.1'
7147 });
7148 return useEntityRecords(kind, name, queryArgs, options);
7149 }
7150
7151 ;// CONCATENATED MODULE: ./packages/core-data/build-module/hooks/use-resource-permissions.js
7152 /**
7153 * WordPress dependencies
7154 */
7155
7156 /**
7157 * Internal dependencies
7158 */
7159
7160
7161
7162
7163
7164 /**
7165 * Resolves resource permissions.
7166 *
7167 * @since 6.1.0 Introduced in WordPress core.
7168 *
7169 * @param resource The resource in question, e.g. media.
7170 * @param id ID of a specific resource entry, if needed, e.g. 10.
7171 *
7172 * @example
7173 * ```js
7174 * import { useResourcePermissions } from '@wordpress/core-data';
7175 *
7176 * function PagesList() {
7177 * const { canCreate, isResolving } = useResourcePermissions( 'pages' );
7178 *
7179 * if ( isResolving ) {
7180 * return 'Loading ...';
7181 * }
7182 *
7183 * return (
7184 * <div>
7185 * {canCreate ? (<button>+ Create a new page</button>) : false}
7186 * // ...
7187 * </div>
7188 * );
7189 * }
7190 *
7191 * // Rendered in the application:
7192 * // <PagesList />
7193 * ```
7194 *
7195 * @example
7196 * ```js
7197 * import { useResourcePermissions } from '@wordpress/core-data';
7198 *
7199 * function Page({ pageId }) {
7200 * const {
7201 * canCreate,
7202 * canUpdate,
7203 * canDelete,
7204 * isResolving
7205 * } = useResourcePermissions( 'pages', pageId );
7206 *
7207 * if ( isResolving ) {
7208 * return 'Loading ...';
7209 * }
7210 *
7211 * return (
7212 * <div>
7213 * {canCreate ? (<button>+ Create a new page</button>) : false}
7214 * {canUpdate ? (<button>Edit page</button>) : false}
7215 * {canDelete ? (<button>Delete page</button>) : false}
7216 * // ...
7217 * </div>
7218 * );
7219 * }
7220 *
7221 * // Rendered in the application:
7222 * // <Page pageId={ 15 } />
7223 * ```
7224 *
7225 * In the above example, when `PagesList` is rendered into an
7226 * application, the appropriate permissions and the resolution details will be retrieved from
7227 * the store state using `canUser()`, or resolved if missing.
7228 *
7229 * @return Entity records data.
7230 * @template IdType
7231 */
7232 function useResourcePermissions(resource, id) {
7233 return useQuerySelect(resolve => {
7234 const {
7235 canUser
7236 } = resolve(store);
7237 const create = canUser('create', resource);
7238
7239 if (!id) {
7240 const read = canUser('read', resource);
7241 const isResolving = create.isResolving || read.isResolving;
7242 const hasResolved = create.hasResolved && read.hasResolved;
7243 let status = Status.Idle;
7244
7245 if (isResolving) {
7246 status = Status.Resolving;
7247 } else if (hasResolved) {
7248 status = Status.Success;
7249 }
7250
7251 return {
7252 status,
7253 isResolving,
7254 hasResolved,
7255 canCreate: create.hasResolved && create.data,
7256 canRead: read.hasResolved && read.data
7257 };
7258 }
7259
7260 const read = canUser('read', resource, id);
7261 const update = canUser('update', resource, id);
7262
7263 const _delete = canUser('delete', resource, id);
7264
7265 const isResolving = read.isResolving || create.isResolving || update.isResolving || _delete.isResolving;
7266 const hasResolved = read.hasResolved && create.hasResolved && update.hasResolved && _delete.hasResolved;
7267 let status = Status.Idle;
7268
7269 if (isResolving) {
7270 status = Status.Resolving;
7271 } else if (hasResolved) {
7272 status = Status.Success;
7273 }
7274
7275 return {
7276 status,
7277 isResolving,
7278 hasResolved,
7279 canRead: hasResolved && read.data,
7280 canCreate: hasResolved && create.data,
7281 canUpdate: hasResolved && update.data,
7282 canDelete: hasResolved && _delete.data
7283 };
7284 }, [resource, id]);
7285 }
7286 function __experimentalUseResourcePermissions(resource, id) {
7287 external_wp_deprecated_default()(`wp.data.__experimentalUseResourcePermissions`, {
7288 alternative: 'wp.data.useResourcePermissions',
7289 since: '6.1'
7290 });
7291 return useResourcePermissions(resource, id);
7292 }
7293
7294 ;// CONCATENATED MODULE: ./packages/core-data/build-module/hooks/index.js
7295
7296
7297
7298
7299 ;// CONCATENATED MODULE: ./packages/core-data/build-module/index.js
7300 /**
7301 * WordPress dependencies
7302 */
7303
7304 /**
7305 * Internal dependencies
7306 */
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316 // The entity selectors/resolvers and actions are shortcuts to their generic equivalents
7317 // (getEntityRecord, getEntityRecords, updateEntityRecord, updateEntityRecords)
7318 // Instead of getEntityRecord, the consumer could use more user-friendly named selector: getPostType, getTaxonomy...
7319 // The "kind" and the "name" of the entity are combined to generate these shortcuts.
7320
7321 const entitySelectors = rootEntitiesConfig.reduce((result, entity) => {
7322 const {
7323 kind,
7324 name
7325 } = entity;
7326
7327 result[getMethodName(kind, name)] = (state, key, query) => getEntityRecord(state, kind, name, key, query);
7328
7329 result[getMethodName(kind, name, 'get', true)] = (state, query) => getEntityRecords(state, kind, name, query);
7330
7331 return result;
7332 }, {});
7333 const entityResolvers = rootEntitiesConfig.reduce((result, entity) => {
7334 const {
7335 kind,
7336 name
7337 } = entity;
7338
7339 result[getMethodName(kind, name)] = (key, query) => resolvers_getEntityRecord(kind, name, key, query);
7340
7341 const pluralMethodName = getMethodName(kind, name, 'get', true);
7342
7343 result[pluralMethodName] = (...args) => resolvers_getEntityRecords(kind, name, ...args);
7344
7345 result[pluralMethodName].shouldInvalidate = action => resolvers_getEntityRecords.shouldInvalidate(action, kind, name);
7346
7347 return result;
7348 }, {});
7349 const entityActions = rootEntitiesConfig.reduce((result, entity) => {
7350 const {
7351 kind,
7352 name
7353 } = entity;
7354
7355 result[getMethodName(kind, name, 'save')] = key => saveEntityRecord(kind, name, key);
7356
7357 result[getMethodName(kind, name, 'delete')] = (key, query) => deleteEntityRecord(kind, name, key, query);
7358
7359 return result;
7360 }, {});
7361
7362 const storeConfig = () => ({
7363 reducer: build_module_reducer,
7364 actions: { ...build_module_actions_namespaceObject,
7365 ...entityActions,
7366 ...createLocksActions()
7367 },
7368 selectors: { ...build_module_selectors_namespaceObject,
7369 ...entitySelectors
7370 },
7371 resolvers: { ...resolvers_namespaceObject,
7372 ...entityResolvers
7373 }
7374 });
7375 /**
7376 * Store definition for the code data namespace.
7377 *
7378 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore
7379 */
7380
7381
7382 const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, storeConfig());
7383 unlock(store).registerPrivateSelectors({
7384 getNavigationFallbackId: getNavigationFallbackId
7385 });
7386 (0,external_wp_data_namespaceObject.register)(store); // Register store after unlocking private selectors to allow resolvers to use them.
7387
7388
7389
7390
7391
7392
7393
7394 })();
7395
7396 (window.wp = window.wp || {}).coreData = __webpack_exports__;
7397 /******/ })()
7398 ;