PluginProbe
Gutenberg / 11.6.0
Gutenberg v11.6.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 11.6.0, at build/core-data/index.js

5,342 lines 155.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (function() { // webpackBootstrap
2 /******/ "use strict";
3 /******/ var __webpack_modules__ = ({
4
5 /***/ 3909:
6 /***/ (function(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 /******/ });
320 /************************************************************************/
321 /******/ // The module cache
322 /******/ var __webpack_module_cache__ = {};
323 /******/
324 /******/ // The require function
325 /******/ function __webpack_require__(moduleId) {
326 /******/ // Check if module is in cache
327 /******/ var cachedModule = __webpack_module_cache__[moduleId];
328 /******/ if (cachedModule !== undefined) {
329 /******/ return cachedModule.exports;
330 /******/ }
331 /******/ // Create a new module (and put it into the cache)
332 /******/ var module = __webpack_module_cache__[moduleId] = {
333 /******/ // no module.id needed
334 /******/ // no module.loaded needed
335 /******/ exports: {}
336 /******/ };
337 /******/
338 /******/ // Execute the module function
339 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
340 /******/
341 /******/ // Return the exports of the module
342 /******/ return module.exports;
343 /******/ }
344 /******/
345 /************************************************************************/
346 /******/ /* webpack/runtime/compat get default export */
347 /******/ !function() {
348 /******/ // getDefaultExport function for compatibility with non-harmony modules
349 /******/ __webpack_require__.n = function(module) {
350 /******/ var getter = module && module.__esModule ?
351 /******/ function() { return module['default']; } :
352 /******/ function() { return module; };
353 /******/ __webpack_require__.d(getter, { a: getter });
354 /******/ return getter;
355 /******/ };
356 /******/ }();
357 /******/
358 /******/ /* webpack/runtime/define property getters */
359 /******/ !function() {
360 /******/ // define getter functions for harmony exports
361 /******/ __webpack_require__.d = function(exports, definition) {
362 /******/ for(var key in definition) {
363 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
364 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
365 /******/ }
366 /******/ }
367 /******/ };
368 /******/ }();
369 /******/
370 /******/ /* webpack/runtime/hasOwnProperty shorthand */
371 /******/ !function() {
372 /******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
373 /******/ }();
374 /******/
375 /******/ /* webpack/runtime/make namespace object */
376 /******/ !function() {
377 /******/ // define __esModule on exports
378 /******/ __webpack_require__.r = function(exports) {
379 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
380 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
381 /******/ }
382 /******/ Object.defineProperty(exports, '__esModule', { value: true });
383 /******/ };
384 /******/ }();
385 /******/
386 /************************************************************************/
387 var __webpack_exports__ = {};
388 // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
389 !function() {
390 // ESM COMPAT FLAG
391 __webpack_require__.r(__webpack_exports__);
392
393 // EXPORTS
394 __webpack_require__.d(__webpack_exports__, {
395 "EntityProvider": function() { return /* reexport */ EntityProvider; },
396 "__experimentalFetchLinkSuggestions": function() { return /* reexport */ _experimental_fetch_link_suggestions; },
397 "__experimentalFetchUrlData": function() { return /* reexport */ _experimental_fetch_url_data; },
398 "store": function() { return /* binding */ store; },
399 "useEntityBlockEditor": function() { return /* reexport */ useEntityBlockEditor; },
400 "useEntityId": function() { return /* reexport */ useEntityId; },
401 "useEntityProp": function() { return /* reexport */ useEntityProp; }
402 });
403
404 // NAMESPACE OBJECT: ./packages/core-data/build-module/actions.js
405 var build_module_actions_namespaceObject = {};
406 __webpack_require__.r(build_module_actions_namespaceObject);
407 __webpack_require__.d(build_module_actions_namespaceObject, {
408 "__experimentalBatch": function() { return __experimentalBatch; },
409 "__experimentalSaveSpecifiedEntityEdits": function() { return __experimentalSaveSpecifiedEntityEdits; },
410 "__unstableCreateUndoLevel": function() { return __unstableCreateUndoLevel; },
411 "addEntities": function() { return addEntities; },
412 "deleteEntityRecord": function() { return deleteEntityRecord; },
413 "editEntityRecord": function() { return editEntityRecord; },
414 "receiveAutosaves": function() { return receiveAutosaves; },
415 "receiveCurrentTheme": function() { return receiveCurrentTheme; },
416 "receiveCurrentUser": function() { return receiveCurrentUser; },
417 "receiveEmbedPreview": function() { return receiveEmbedPreview; },
418 "receiveEntityRecords": function() { return receiveEntityRecords; },
419 "receiveThemeSupports": function() { return receiveThemeSupports; },
420 "receiveUploadPermissions": function() { return receiveUploadPermissions; },
421 "receiveUserPermission": function() { return receiveUserPermission; },
422 "receiveUserQuery": function() { return receiveUserQuery; },
423 "redo": function() { return redo; },
424 "saveEditedEntityRecord": function() { return saveEditedEntityRecord; },
425 "saveEntityRecord": function() { return saveEntityRecord; },
426 "undo": function() { return undo; }
427 });
428
429 // NAMESPACE OBJECT: ./packages/core-data/build-module/selectors.js
430 var build_module_selectors_namespaceObject = {};
431 __webpack_require__.r(build_module_selectors_namespaceObject);
432 __webpack_require__.d(build_module_selectors_namespaceObject, {
433 "__experimentalGetDirtyEntityRecords": function() { return __experimentalGetDirtyEntityRecords; },
434 "__experimentalGetEntitiesBeingSaved": function() { return __experimentalGetEntitiesBeingSaved; },
435 "__experimentalGetEntityRecordNoResolver": function() { return __experimentalGetEntityRecordNoResolver; },
436 "__experimentalGetTemplateForLink": function() { return __experimentalGetTemplateForLink; },
437 "canUser": function() { return canUser; },
438 "canUserEditEntityRecord": function() { return canUserEditEntityRecord; },
439 "getAuthors": function() { return getAuthors; },
440 "getAutosave": function() { return getAutosave; },
441 "getAutosaves": function() { return getAutosaves; },
442 "getCurrentTheme": function() { return getCurrentTheme; },
443 "getCurrentUser": function() { return getCurrentUser; },
444 "getEditedEntityRecord": function() { return getEditedEntityRecord; },
445 "getEmbedPreview": function() { return getEmbedPreview; },
446 "getEntitiesByKind": function() { return getEntitiesByKind; },
447 "getEntity": function() { return getEntity; },
448 "getEntityRecord": function() { return getEntityRecord; },
449 "getEntityRecordEdits": function() { return getEntityRecordEdits; },
450 "getEntityRecordNonTransientEdits": function() { return getEntityRecordNonTransientEdits; },
451 "getEntityRecords": function() { return getEntityRecords; },
452 "getLastEntityDeleteError": function() { return getLastEntityDeleteError; },
453 "getLastEntitySaveError": function() { return getLastEntitySaveError; },
454 "getRawEntityRecord": function() { return getRawEntityRecord; },
455 "getRedoEdit": function() { return getRedoEdit; },
456 "getReferenceByDistinctEdits": function() { return getReferenceByDistinctEdits; },
457 "getThemeSupports": function() { return getThemeSupports; },
458 "getUndoEdit": function() { return getUndoEdit; },
459 "getUserQueryResults": function() { return getUserQueryResults; },
460 "hasEditsForEntityRecord": function() { return hasEditsForEntityRecord; },
461 "hasEntityRecords": function() { return hasEntityRecords; },
462 "hasFetchedAutosaves": function() { return hasFetchedAutosaves; },
463 "hasRedo": function() { return hasRedo; },
464 "hasUndo": function() { return hasUndo; },
465 "isAutosavingEntityRecord": function() { return isAutosavingEntityRecord; },
466 "isDeletingEntityRecord": function() { return isDeletingEntityRecord; },
467 "isPreviewEmbedFallback": function() { return isPreviewEmbedFallback; },
468 "isRequestingEmbedPreview": function() { return isRequestingEmbedPreview; },
469 "isSavingEntityRecord": function() { return isSavingEntityRecord; }
470 });
471
472 // NAMESPACE OBJECT: ./packages/core-data/build-module/resolvers.js
473 var resolvers_namespaceObject = {};
474 __webpack_require__.r(resolvers_namespaceObject);
475 __webpack_require__.d(resolvers_namespaceObject, {
476 "__experimentalGetTemplateForLink": function() { return resolvers_experimentalGetTemplateForLink; },
477 "canUser": function() { return resolvers_canUser; },
478 "canUserEditEntityRecord": function() { return resolvers_canUserEditEntityRecord; },
479 "getAuthors": function() { return resolvers_getAuthors; },
480 "getAutosave": function() { return resolvers_getAutosave; },
481 "getAutosaves": function() { return resolvers_getAutosaves; },
482 "getCurrentTheme": function() { return resolvers_getCurrentTheme; },
483 "getCurrentUser": function() { return resolvers_getCurrentUser; },
484 "getEditedEntityRecord": function() { return resolvers_getEditedEntityRecord; },
485 "getEmbedPreview": function() { return resolvers_getEmbedPreview; },
486 "getEntityRecord": function() { return resolvers_getEntityRecord; },
487 "getEntityRecords": function() { return resolvers_getEntityRecords; },
488 "getRawEntityRecord": function() { return resolvers_getRawEntityRecord; },
489 "getThemeSupports": function() { return resolvers_getThemeSupports; }
490 });
491
492 ;// CONCATENATED MODULE: external ["wp","data"]
493 var external_wp_data_namespaceObject = window["wp"]["data"];
494 ;// CONCATENATED MODULE: external "lodash"
495 var external_lodash_namespaceObject = window["lodash"];
496 ;// CONCATENATED MODULE: external ["wp","isShallowEqual"]
497 var external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"];
498 var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject);
499 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/if-matching-action.js
500 /**
501 * A higher-order reducer creator which invokes the original reducer only if
502 * the dispatching action matches the given predicate, **OR** if state is
503 * initializing (undefined).
504 *
505 * @param {Function} isMatch Function predicate for allowing reducer call.
506 *
507 * @return {Function} Higher-order reducer.
508 */
509 const ifMatchingAction = isMatch => reducer => (state, action) => {
510 if (state === undefined || isMatch(action)) {
511 return reducer(state, action);
512 }
513
514 return state;
515 };
516
517 /* harmony default export */ var if_matching_action = (ifMatchingAction);
518 //# sourceMappingURL=if-matching-action.js.map
519 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/replace-action.js
520 /**
521 * Higher-order reducer creator which substitutes the action object before
522 * passing to the original reducer.
523 *
524 * @param {Function} replacer Function mapping original action to replacement.
525 *
526 * @return {Function} Higher-order reducer.
527 */
528 const replaceAction = replacer => reducer => (state, action) => {
529 return reducer(state, replacer(action));
530 };
531
532 /* harmony default export */ var replace_action = (replaceAction);
533 //# sourceMappingURL=replace-action.js.map
534 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/conservative-map-item.js
535 /**
536 * External dependencies
537 */
538
539 /**
540 * Given the current and next item entity, returns the minimally "modified"
541 * result of the next item, preferring value references from the original item
542 * if equal. If all values match, the original item is returned.
543 *
544 * @param {Object} item Original item.
545 * @param {Object} nextItem Next item.
546 *
547 * @return {Object} Minimally modified merged item.
548 */
549
550 function conservativeMapItem(item, nextItem) {
551 // Return next item in its entirety if there is no original item.
552 if (!item) {
553 return nextItem;
554 }
555
556 let hasChanges = false;
557 const result = {};
558
559 for (const key in nextItem) {
560 if ((0,external_lodash_namespaceObject.isEqual)(item[key], nextItem[key])) {
561 result[key] = item[key];
562 } else {
563 hasChanges = true;
564 result[key] = nextItem[key];
565 }
566 }
567
568 if (!hasChanges) {
569 return item;
570 } // Only at this point, backfill properties from the original item which
571 // weren't explicitly set into the result above. This is an optimization
572 // to allow `hasChanges` to return early.
573
574
575 for (const key in item) {
576 if (!result.hasOwnProperty(key)) {
577 result[key] = item[key];
578 }
579 }
580
581 return result;
582 }
583 //# sourceMappingURL=conservative-map-item.js.map
584 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/on-sub-key.js
585 /**
586 * Higher-order reducer creator which creates a combined reducer object, keyed
587 * by a property on the action object.
588 *
589 * @param {string} actionProperty Action property by which to key object.
590 *
591 * @return {Function} Higher-order reducer.
592 */
593 const onSubKey = actionProperty => reducer => (state = {}, action) => {
594 // Retrieve subkey from action. Do not track if undefined; useful for cases
595 // where reducer is scoped by action shape.
596 const key = action[actionProperty];
597
598 if (key === undefined) {
599 return state;
600 } // Avoid updating state if unchanged. Note that this also accounts for a
601 // reducer which returns undefined on a key which is not yet tracked.
602
603
604 const nextKeyState = reducer(state[key], action);
605
606 if (nextKeyState === state[key]) {
607 return state;
608 }
609
610 return { ...state,
611 [key]: nextKeyState
612 };
613 };
614 /* harmony default export */ var on_sub_key = (onSubKey);
615 //# sourceMappingURL=on-sub-key.js.map
616 ;// CONCATENATED MODULE: external ["wp","apiFetch"]
617 var external_wp_apiFetch_namespaceObject = window["wp"]["apiFetch"];
618 var external_wp_apiFetch_default = /*#__PURE__*/__webpack_require__.n(external_wp_apiFetch_namespaceObject);
619 ;// CONCATENATED MODULE: external ["wp","i18n"]
620 var external_wp_i18n_namespaceObject = window["wp"]["i18n"];
621 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/rng.js
622 // Unique ID creation requires a high quality random # generator. In the browser we therefore
623 // require the crypto API and do not support built-in fallback to lower quality random number
624 // generators (like Math.random()).
625 // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
626 // find the complete implementation of crypto (msCrypto) on IE11.
627 var getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
628 var rnds8 = new Uint8Array(16);
629 function rng() {
630 if (!getRandomValues) {
631 throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
632 }
633
634 return getRandomValues(rnds8);
635 }
636 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/regex.js
637 /* harmony default export */ var 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);
638 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/validate.js
639
640
641 function validate(uuid) {
642 return typeof uuid === 'string' && regex.test(uuid);
643 }
644
645 /* harmony default export */ var esm_browser_validate = (validate);
646 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/stringify.js
647
648 /**
649 * Convert array of 16 byte values to UUID string format of the form:
650 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
651 */
652
653 var byteToHex = [];
654
655 for (var i = 0; i < 256; ++i) {
656 byteToHex.push((i + 0x100).toString(16).substr(1));
657 }
658
659 function stringify(arr) {
660 var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
661 // Note: Be careful editing this code! It's been tuned for performance
662 // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
663 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
664 // of the following:
665 // - One or more input array values don't map to a hex octet (leading to
666 // "undefined" in the uuid)
667 // - Invalid input values for the RFC `version` or `variant` fields
668
669 if (!esm_browser_validate(uuid)) {
670 throw TypeError('Stringified UUID is invalid');
671 }
672
673 return uuid;
674 }
675
676 /* harmony default export */ var esm_browser_stringify = (stringify);
677 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/v4.js
678
679
680
681 function v4(options, buf, offset) {
682 options = options || {};
683 var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
684
685 rnds[6] = rnds[6] & 0x0f | 0x40;
686 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
687
688 if (buf) {
689 offset = offset || 0;
690
691 for (var i = 0; i < 16; ++i) {
692 buf[offset + i] = rnds[i];
693 }
694
695 return buf;
696 }
697
698 return esm_browser_stringify(rnds);
699 }
700
701 /* harmony default export */ var esm_browser_v4 = (v4);
702 ;// CONCATENATED MODULE: external ["wp","url"]
703 var external_wp_url_namespaceObject = window["wp"]["url"];
704 ;// CONCATENATED MODULE: ./packages/core-data/build-module/queried-data/actions.js
705 /**
706 * External dependencies
707 */
708
709 /**
710 * Returns an action object used in signalling that items have been received.
711 *
712 * @param {Array} items Items received.
713 * @param {?Object} edits Optional edits to reset.
714 *
715 * @return {Object} Action object.
716 */
717
718 function receiveItems(items, edits) {
719 return {
720 type: 'RECEIVE_ITEMS',
721 items: (0,external_lodash_namespaceObject.castArray)(items),
722 persistedEdits: edits
723 };
724 }
725 /**
726 * Returns an action object used in signalling that entity records have been
727 * deleted and they need to be removed from entities state.
728 *
729 * @param {string} kind Kind of the removed entities.
730 * @param {string} name Name of the removed entities.
731 * @param {Array|number} records Record IDs of the removed entities.
732 * @param {boolean} invalidateCache Controls whether we want to invalidate the cache.
733 * @return {Object} Action object.
734 */
735
736 function removeItems(kind, name, records, invalidateCache = false) {
737 return {
738 type: 'REMOVE_ITEMS',
739 itemIds: (0,external_lodash_namespaceObject.castArray)(records),
740 kind,
741 name,
742 invalidateCache
743 };
744 }
745 /**
746 * Returns an action object used in signalling that queried data has been
747 * received.
748 *
749 * @param {Array} items Queried items received.
750 * @param {?Object} query Optional query object.
751 * @param {?Object} edits Optional edits to reset.
752 *
753 * @return {Object} Action object.
754 */
755
756 function receiveQueriedItems(items, query = {}, edits) {
757 return { ...receiveItems(items, edits),
758 query
759 };
760 }
761 //# sourceMappingURL=actions.js.map
762 ;// CONCATENATED MODULE: ./packages/core-data/build-module/batch/default-processor.js
763 /**
764 * External dependencies
765 */
766
767 /**
768 * WordPress dependencies
769 */
770
771
772 /**
773 * Maximum number of requests to place in a single batch request. Obtained by
774 * sending a preflight OPTIONS request to /batch/v1/.
775 *
776 * @type {number?}
777 */
778
779 let maxItems = null;
780 /**
781 * Default batch processor. Sends its input requests to /batch/v1.
782 *
783 * @param {Array} requests List of API requests to perform at once.
784 *
785 * @return {Promise} Promise that resolves to a list of objects containing
786 * either `output` (if that request was succesful) or `error`
787 * (if not ).
788 */
789
790 async function defaultProcessor(requests) {
791 if (maxItems === null) {
792 const preflightResponse = await external_wp_apiFetch_default()({
793 path: '/batch/v1',
794 method: 'OPTIONS'
795 });
796 maxItems = preflightResponse.endpoints[0].args.requests.maxItems;
797 }
798
799 const results = [];
800
801 for (const batchRequests of (0,external_lodash_namespaceObject.chunk)(requests, maxItems)) {
802 const batchResponse = await external_wp_apiFetch_default()({
803 path: '/batch/v1',
804 method: 'POST',
805 data: {
806 validation: 'require-all-validate',
807 requests: batchRequests.map(request => ({
808 path: request.path,
809 body: request.data,
810 // Rename 'data' to 'body'.
811 method: request.method,
812 headers: request.headers
813 }))
814 }
815 });
816 let batchResults;
817
818 if (batchResponse.failed) {
819 batchResults = batchResponse.responses.map(response => ({
820 error: response === null || response === void 0 ? void 0 : response.body
821 }));
822 } else {
823 batchResults = batchResponse.responses.map(response => {
824 const result = {};
825
826 if (response.status >= 200 && response.status < 300) {
827 result.output = response.body;
828 } else {
829 result.error = response.body;
830 }
831
832 return result;
833 });
834 }
835
836 results.push(...batchResults);
837 }
838
839 return results;
840 }
841 //# sourceMappingURL=default-processor.js.map
842 ;// CONCATENATED MODULE: ./packages/core-data/build-module/batch/create-batch.js
843 /**
844 * External dependencies
845 */
846
847 /**
848 * Internal dependencies
849 */
850
851
852 /**
853 * Creates a batch, which can be used to combine multiple API requests into one
854 * API request using the WordPress batch processing API (/v1/batch).
855 *
856 * ```
857 * const batch = createBatch();
858 * const dunePromise = batch.add( {
859 * path: '/v1/books',
860 * method: 'POST',
861 * data: { title: 'Dune' }
862 * } );
863 * const lotrPromise = batch.add( {
864 * path: '/v1/books',
865 * method: 'POST',
866 * data: { title: 'Lord of the Rings' }
867 * } );
868 * const isSuccess = await batch.run(); // Sends one POST to /v1/batch.
869 * if ( isSuccess ) {
870 * console.log(
871 * 'Saved two books:',
872 * await dunePromise,
873 * await lotrPromise
874 * );
875 * }
876 * ```
877 *
878 * @param {Function} [processor] Processor function. Can be used to replace the
879 * default functionality which is to send an API
880 * request to /v1/batch. Is given an array of
881 * inputs and must return a promise that
882 * resolves to an array of objects containing
883 * either `output` or `error`.
884 */
885
886 function createBatch(processor = defaultProcessor) {
887 let lastId = 0;
888 let queue = [];
889 const pending = new ObservableSet();
890 return {
891 /**
892 * Adds an input to the batch and returns a promise that is resolved or
893 * rejected when the input is processed by `batch.run()`.
894 *
895 * You may also pass a thunk which allows inputs to be added
896 * asychronously.
897 *
898 * ```
899 * // Both are allowed:
900 * batch.add( { path: '/v1/books', ... } );
901 * batch.add( ( add ) => add( { path: '/v1/books', ... } ) );
902 * ```
903 *
904 * If a thunk is passed, `batch.run()` will pause until either:
905 *
906 * - The thunk calls its `add` argument, or;
907 * - The thunk returns a promise and that promise resolves, or;
908 * - The thunk returns a non-promise.
909 *
910 * @param {any|Function} inputOrThunk Input to add or thunk to execute.
911 *
912 * @return {Promise|any} If given an input, returns a promise that
913 * is resolved or rejected when the batch is
914 * processed. If given a thunk, returns the return
915 * value of that thunk.
916 */
917 add(inputOrThunk) {
918 const id = ++lastId;
919 pending.add(id);
920
921 const add = input => new Promise((resolve, reject) => {
922 queue.push({
923 input,
924 resolve,
925 reject
926 });
927 pending.delete(id);
928 });
929
930 if ((0,external_lodash_namespaceObject.isFunction)(inputOrThunk)) {
931 return Promise.resolve(inputOrThunk(add)).finally(() => {
932 pending.delete(id);
933 });
934 }
935
936 return add(inputOrThunk);
937 },
938
939 /**
940 * Runs the batch. This calls `batchProcessor` and resolves or rejects
941 * all promises returned by `add()`.
942 *
943 * @return {Promise} A promise that resolves to a boolean that is true
944 * if the processor returned no errors.
945 */
946 async run() {
947 if (pending.size) {
948 await new Promise(resolve => {
949 const unsubscribe = pending.subscribe(() => {
950 if (!pending.size) {
951 unsubscribe();
952 resolve();
953 }
954 });
955 });
956 }
957
958 let results;
959
960 try {
961 results = await processor(queue.map(({
962 input
963 }) => input));
964
965 if (results.length !== queue.length) {
966 throw new Error('run: Array returned by processor must be same size as input array.');
967 }
968 } catch (error) {
969 for (const {
970 reject
971 } of queue) {
972 reject(error);
973 }
974
975 throw error;
976 }
977
978 let isSuccess = true;
979
980 for (const [result, {
981 resolve,
982 reject
983 }] of (0,external_lodash_namespaceObject.zip)(results, queue)) {
984 if (result !== null && result !== void 0 && result.error) {
985 reject(result.error);
986 isSuccess = false;
987 } else {
988 var _result$output;
989
990 resolve((_result$output = result === null || result === void 0 ? void 0 : result.output) !== null && _result$output !== void 0 ? _result$output : result);
991 }
992 }
993
994 queue = [];
995 return isSuccess;
996 }
997
998 };
999 }
1000
1001 class ObservableSet {
1002 constructor(...args) {
1003 this.set = new Set(...args);
1004 this.subscribers = new Set();
1005 }
1006
1007 get size() {
1008 return this.set.size;
1009 }
1010
1011 add(...args) {
1012 this.set.add(...args);
1013 this.subscribers.forEach(subscriber => subscriber());
1014 return this;
1015 }
1016
1017 delete(...args) {
1018 const isSuccess = this.set.delete(...args);
1019 this.subscribers.forEach(subscriber => subscriber());
1020 return isSuccess;
1021 }
1022
1023 subscribe(subscriber) {
1024 this.subscribers.add(subscriber);
1025 return () => {
1026 this.subscribers.delete(subscriber);
1027 };
1028 }
1029
1030 }
1031 //# sourceMappingURL=create-batch.js.map
1032 ;// CONCATENATED MODULE: ./packages/core-data/build-module/name.js
1033 /**
1034 * The reducer key used by core data in store registration.
1035 * This is defined in a separate file to avoid cycle-dependency
1036 *
1037 * @type {string}
1038 */
1039 const STORE_NAME = 'core';
1040 //# sourceMappingURL=name.js.map
1041 ;// CONCATENATED MODULE: ./packages/core-data/build-module/actions.js
1042 /**
1043 * External dependencies
1044 */
1045
1046
1047 /**
1048 * WordPress dependencies
1049 */
1050
1051
1052
1053 /**
1054 * Internal dependencies
1055 */
1056
1057
1058
1059
1060
1061 /**
1062 * Returns an action object used in signalling that authors have been received.
1063 *
1064 * @param {string} queryID Query ID.
1065 * @param {Array|Object} users Users received.
1066 *
1067 * @return {Object} Action object.
1068 */
1069
1070 function receiveUserQuery(queryID, users) {
1071 return {
1072 type: 'RECEIVE_USER_QUERY',
1073 users: (0,external_lodash_namespaceObject.castArray)(users),
1074 queryID
1075 };
1076 }
1077 /**
1078 * Returns an action used in signalling that the current user has been received.
1079 *
1080 * @param {Object} currentUser Current user object.
1081 *
1082 * @return {Object} Action object.
1083 */
1084
1085 function receiveCurrentUser(currentUser) {
1086 return {
1087 type: 'RECEIVE_CURRENT_USER',
1088 currentUser
1089 };
1090 }
1091 /**
1092 * Returns an action object used in adding new entities.
1093 *
1094 * @param {Array} entities Entities received.
1095 *
1096 * @return {Object} Action object.
1097 */
1098
1099 function addEntities(entities) {
1100 return {
1101 type: 'ADD_ENTITIES',
1102 entities
1103 };
1104 }
1105 /**
1106 * Returns an action object used in signalling that entity records have been received.
1107 *
1108 * @param {string} kind Kind of the received entity.
1109 * @param {string} name Name of the received entity.
1110 * @param {Array|Object} records Records received.
1111 * @param {?Object} query Query Object.
1112 * @param {?boolean} invalidateCache Should invalidate query caches.
1113 * @param {?Object} edits Edits to reset.
1114 * @return {Object} Action object.
1115 */
1116
1117 function receiveEntityRecords(kind, name, records, query, invalidateCache = false, edits) {
1118 // Auto drafts should not have titles, but some plugins rely on them so we can't filter this
1119 // on the server.
1120 if (kind === 'postType') {
1121 records = (0,external_lodash_namespaceObject.castArray)(records).map(record => record.status === 'auto-draft' ? { ...record,
1122 title: ''
1123 } : record);
1124 }
1125
1126 let action;
1127
1128 if (query) {
1129 action = receiveQueriedItems(records, query, edits);
1130 } else {
1131 action = receiveItems(records, edits);
1132 }
1133
1134 return { ...action,
1135 kind,
1136 name,
1137 invalidateCache
1138 };
1139 }
1140 /**
1141 * Returns an action object used in signalling that the current theme has been received.
1142 *
1143 * @param {Object} currentTheme The current theme.
1144 *
1145 * @return {Object} Action object.
1146 */
1147
1148 function receiveCurrentTheme(currentTheme) {
1149 return {
1150 type: 'RECEIVE_CURRENT_THEME',
1151 currentTheme
1152 };
1153 }
1154 /**
1155 * Returns an action object used in signalling that the index has been received.
1156 *
1157 * @param {Object} themeSupports Theme support for the current theme.
1158 *
1159 * @return {Object} Action object.
1160 */
1161
1162 function receiveThemeSupports(themeSupports) {
1163 return {
1164 type: 'RECEIVE_THEME_SUPPORTS',
1165 themeSupports
1166 };
1167 }
1168 /**
1169 * Returns an action object used in signalling that the preview data for
1170 * a given URl has been received.
1171 *
1172 * @param {string} url URL to preview the embed for.
1173 * @param {*} preview Preview data.
1174 *
1175 * @return {Object} Action object.
1176 */
1177
1178 function receiveEmbedPreview(url, preview) {
1179 return {
1180 type: 'RECEIVE_EMBED_PREVIEW',
1181 url,
1182 preview
1183 };
1184 }
1185 /**
1186 * Action triggered to delete an entity record.
1187 *
1188 * @param {string} kind Kind of the deleted entity.
1189 * @param {string} name Name of the deleted entity.
1190 * @param {string} recordId Record ID of the deleted entity.
1191 * @param {?Object} query Special query parameters for the
1192 * DELETE API call.
1193 * @param {Object} [options] Delete options.
1194 * @param {Function} [options.__unstableFetch] Internal use only. Function to
1195 * call instead of `apiFetch()`.
1196 * Must return a promise.
1197 */
1198
1199 const deleteEntityRecord = (kind, name, recordId, query, {
1200 __unstableFetch = (external_wp_apiFetch_default())
1201 } = {}) => async ({
1202 dispatch
1203 }) => {
1204 const entities = await dispatch(getKindEntities(kind));
1205 const entity = (0,external_lodash_namespaceObject.find)(entities, {
1206 kind,
1207 name
1208 });
1209 let error;
1210 let deletedRecord = false;
1211
1212 if (!entity || entity !== null && entity !== void 0 && entity.__experimentalNoFetch) {
1213 return;
1214 }
1215
1216 const lock = await dispatch.__unstableAcquireStoreLock(STORE_NAME, ['entities', 'data', kind, name, recordId], {
1217 exclusive: true
1218 });
1219
1220 try {
1221 dispatch({
1222 type: 'DELETE_ENTITY_RECORD_START',
1223 kind,
1224 name,
1225 recordId
1226 });
1227
1228 try {
1229 let path = `${entity.baseURL}/${recordId}`;
1230
1231 if (query) {
1232 path = (0,external_wp_url_namespaceObject.addQueryArgs)(path, query);
1233 }
1234
1235 deletedRecord = await __unstableFetch({
1236 path,
1237 method: 'DELETE'
1238 });
1239 await dispatch(removeItems(kind, name, recordId, true));
1240 } catch (_error) {
1241 error = _error;
1242 }
1243
1244 dispatch({
1245 type: 'DELETE_ENTITY_RECORD_FINISH',
1246 kind,
1247 name,
1248 recordId,
1249 error
1250 });
1251 return deletedRecord;
1252 } finally {
1253 dispatch.__unstableReleaseStoreLock(lock);
1254 }
1255 };
1256 /**
1257 * Returns an action object that triggers an
1258 * edit to an entity record.
1259 *
1260 * @param {string} kind Kind of the edited entity record.
1261 * @param {string} name Name of the edited entity record.
1262 * @param {number} recordId Record ID of the edited entity record.
1263 * @param {Object} edits The edits.
1264 * @param {Object} options Options for the edit.
1265 * @param {boolean} options.undoIgnore Whether to ignore the edit in undo history or not.
1266 *
1267 * @return {Object} Action object.
1268 */
1269
1270 const editEntityRecord = (kind, name, recordId, edits, options = {}) => ({
1271 select,
1272 dispatch
1273 }) => {
1274 const entity = select.getEntity(kind, name);
1275
1276 if (!entity) {
1277 throw new Error(`The entity being edited (${kind}, ${name}) does not have a loaded config.`);
1278 }
1279
1280 const {
1281 transientEdits = {},
1282 mergedEdits = {}
1283 } = entity;
1284 const record = select.getRawEntityRecord(kind, name, recordId);
1285 const editedRecord = select.getEditedEntityRecord(kind, name, recordId);
1286 const edit = {
1287 kind,
1288 name,
1289 recordId,
1290 // Clear edits when they are equal to their persisted counterparts
1291 // so that the property is not considered dirty.
1292 edits: Object.keys(edits).reduce((acc, key) => {
1293 const recordValue = record[key];
1294 const editedRecordValue = editedRecord[key];
1295 const value = mergedEdits[key] ? { ...editedRecordValue,
1296 ...edits[key]
1297 } : edits[key];
1298 acc[key] = (0,external_lodash_namespaceObject.isEqual)(recordValue, value) ? undefined : value;
1299 return acc;
1300 }, {}),
1301 transientEdits
1302 };
1303 dispatch({
1304 type: 'EDIT_ENTITY_RECORD',
1305 ...edit,
1306 meta: {
1307 undo: !options.undoIgnore && { ...edit,
1308 // Send the current values for things like the first undo stack entry.
1309 edits: Object.keys(edits).reduce((acc, key) => {
1310 acc[key] = editedRecord[key];
1311 return acc;
1312 }, {})
1313 }
1314 }
1315 });
1316 };
1317 /**
1318 * Action triggered to undo the last edit to
1319 * an entity record, if any.
1320 *
1321 * @return {undefined}
1322 */
1323
1324 const undo = () => ({
1325 select,
1326 dispatch
1327 }) => {
1328 const undoEdit = select.getUndoEdit();
1329
1330 if (!undoEdit) {
1331 return;
1332 }
1333
1334 dispatch({
1335 type: 'EDIT_ENTITY_RECORD',
1336 ...undoEdit,
1337 meta: {
1338 isUndo: true
1339 }
1340 });
1341 };
1342 /**
1343 * Action triggered to redo the last undoed
1344 * edit to an entity record, if any.
1345 *
1346 * @return {undefined}
1347 */
1348
1349 const redo = () => ({
1350 select,
1351 dispatch
1352 }) => {
1353 const redoEdit = select.getRedoEdit();
1354
1355 if (!redoEdit) {
1356 return;
1357 }
1358
1359 dispatch({
1360 type: 'EDIT_ENTITY_RECORD',
1361 ...redoEdit,
1362 meta: {
1363 isRedo: true
1364 }
1365 });
1366 };
1367 /**
1368 * Forces the creation of a new undo level.
1369 *
1370 * @return {Object} Action object.
1371 */
1372
1373 function __unstableCreateUndoLevel() {
1374 return {
1375 type: 'CREATE_UNDO_LEVEL'
1376 };
1377 }
1378 /**
1379 * Action triggered to save an entity record.
1380 *
1381 * @param {string} kind Kind of the received entity.
1382 * @param {string} name Name of the received entity.
1383 * @param {Object} record Record to be saved.
1384 * @param {Object} options Saving options.
1385 * @param {boolean} [options.isAutosave=false] Whether this is an autosave.
1386 * @param {Function} [options.__unstableFetch] Internal use only. Function to
1387 * call instead of `apiFetch()`.
1388 * Must return a promise.
1389 */
1390
1391 const saveEntityRecord = (kind, name, record, {
1392 isAutosave = false,
1393 __unstableFetch = (external_wp_apiFetch_default())
1394 } = {}) => async ({
1395 select,
1396 resolveSelect,
1397 dispatch
1398 }) => {
1399 const entities = await dispatch(getKindEntities(kind));
1400 const entity = (0,external_lodash_namespaceObject.find)(entities, {
1401 kind,
1402 name
1403 });
1404
1405 if (!entity || entity !== null && entity !== void 0 && entity.__experimentalNoFetch) {
1406 return;
1407 }
1408
1409 const entityIdKey = entity.key || DEFAULT_ENTITY_KEY;
1410 const recordId = record[entityIdKey];
1411 const lock = await dispatch.__unstableAcquireStoreLock(STORE_NAME, ['entities', 'data', kind, name, recordId || esm_browser_v4()], {
1412 exclusive: true
1413 });
1414
1415 try {
1416 // Evaluate optimized edits.
1417 // (Function edits that should be evaluated on save to avoid expensive computations on every edit.)
1418 for (const [key, value] of Object.entries(record)) {
1419 if (typeof value === 'function') {
1420 const evaluatedValue = value(select.getEditedEntityRecord(kind, name, recordId));
1421 dispatch.editEntityRecord(kind, name, recordId, {
1422 [key]: evaluatedValue
1423 }, {
1424 undoIgnore: true
1425 });
1426 record[key] = evaluatedValue;
1427 }
1428 }
1429
1430 dispatch({
1431 type: 'SAVE_ENTITY_RECORD_START',
1432 kind,
1433 name,
1434 recordId,
1435 isAutosave
1436 });
1437 let updatedRecord;
1438 let error;
1439
1440 try {
1441 const path = `${entity.baseURL}${recordId ? '/' + recordId : ''}`;
1442 const persistedRecord = select.getRawEntityRecord(kind, name, recordId);
1443
1444 if (isAutosave) {
1445 // Most of this autosave logic is very specific to posts.
1446 // This is fine for now as it is the only supported autosave,
1447 // but ideally this should all be handled in the back end,
1448 // so the client just sends and receives objects.
1449 const currentUser = select.getCurrentUser();
1450 const currentUserId = currentUser ? currentUser.id : undefined;
1451 const autosavePost = resolveSelect.getAutosave(persistedRecord.type, persistedRecord.id, currentUserId); // Autosaves need all expected fields to be present.
1452 // So we fallback to the previous autosave and then
1453 // to the actual persisted entity if the edits don't
1454 // have a value.
1455
1456 let data = { ...persistedRecord,
1457 ...autosavePost,
1458 ...record
1459 };
1460 data = Object.keys(data).reduce((acc, key) => {
1461 if (['title', 'excerpt', 'content'].includes(key)) {
1462 acc[key] = data[key];
1463 }
1464
1465 return acc;
1466 }, {
1467 status: data.status === 'auto-draft' ? 'draft' : data.status
1468 });
1469 updatedRecord = await __unstableFetch({
1470 path: `${path}/autosaves`,
1471 method: 'POST',
1472 data
1473 }); // An autosave may be processed by the server as a regular save
1474 // when its update is requested by the author and the post had
1475 // draft or auto-draft status.
1476
1477 if (persistedRecord.id === updatedRecord.id) {
1478 let newRecord = { ...persistedRecord,
1479 ...data,
1480 ...updatedRecord
1481 };
1482 newRecord = Object.keys(newRecord).reduce((acc, key) => {
1483 // These properties are persisted in autosaves.
1484 if (['title', 'excerpt', 'content'].includes(key)) {
1485 acc[key] = newRecord[key];
1486 } else if (key === 'status') {
1487 // Status is only persisted in autosaves when going from
1488 // "auto-draft" to "draft".
1489 acc[key] = persistedRecord.status === 'auto-draft' && newRecord.status === 'draft' ? newRecord.status : persistedRecord.status;
1490 } else {
1491 // These properties are not persisted in autosaves.
1492 acc[key] = persistedRecord[key];
1493 }
1494
1495 return acc;
1496 }, {});
1497 dispatch.receiveEntityRecords(kind, name, newRecord, undefined, true);
1498 } else {
1499 dispatch.receiveAutosaves(persistedRecord.id, updatedRecord);
1500 }
1501 } else {
1502 let edits = record;
1503
1504 if (entity.__unstablePrePersist) {
1505 edits = { ...edits,
1506 ...entity.__unstablePrePersist(persistedRecord, edits)
1507 };
1508 }
1509
1510 updatedRecord = await __unstableFetch({
1511 path,
1512 method: recordId ? 'PUT' : 'POST',
1513 data: edits
1514 });
1515 dispatch.receiveEntityRecords(kind, name, updatedRecord, undefined, true, edits);
1516 }
1517 } catch (_error) {
1518 error = _error;
1519 }
1520
1521 dispatch({
1522 type: 'SAVE_ENTITY_RECORD_FINISH',
1523 kind,
1524 name,
1525 recordId,
1526 error,
1527 isAutosave
1528 });
1529 return updatedRecord;
1530 } finally {
1531 dispatch.__unstableReleaseStoreLock(lock);
1532 }
1533 };
1534 /**
1535 * Runs multiple core-data actions at the same time using one API request.
1536 *
1537 * Example:
1538 *
1539 * ```
1540 * const [ savedRecord, updatedRecord, deletedRecord ] =
1541 * await dispatch( 'core' ).__experimentalBatch( [
1542 * ( { saveEntityRecord } ) => saveEntityRecord( 'root', 'widget', widget ),
1543 * ( { saveEditedEntityRecord } ) => saveEntityRecord( 'root', 'widget', 123 ),
1544 * ( { deleteEntityRecord } ) => deleteEntityRecord( 'root', 'widget', 123, null ),
1545 * ] );
1546 * ```
1547 *
1548 * @param {Array} requests Array of functions which are invoked simultaneously.
1549 * Each function is passed an object containing
1550 * `saveEntityRecord`, `saveEditedEntityRecord`, and
1551 * `deleteEntityRecord`.
1552 *
1553 * @return {Promise} A promise that resolves to an array containing the return
1554 * values of each function given in `requests`.
1555 */
1556
1557 const __experimentalBatch = requests => async ({
1558 dispatch
1559 }) => {
1560 const batch = createBatch();
1561 const api = {
1562 saveEntityRecord(kind, name, record, options) {
1563 return batch.add(add => dispatch.saveEntityRecord(kind, name, record, { ...options,
1564 __unstableFetch: add
1565 }));
1566 },
1567
1568 saveEditedEntityRecord(kind, name, recordId, options) {
1569 return batch.add(add => dispatch.saveEditedEntityRecord(kind, name, recordId, { ...options,
1570 __unstableFetch: add
1571 }));
1572 },
1573
1574 deleteEntityRecord(kind, name, recordId, query, options) {
1575 return batch.add(add => dispatch.deleteEntityRecord(kind, name, recordId, query, { ...options,
1576 __unstableFetch: add
1577 }));
1578 }
1579
1580 };
1581 const resultPromises = requests.map(request => request(api));
1582 const [, ...results] = await Promise.all([batch.run(), ...resultPromises]);
1583 return results;
1584 };
1585 /**
1586 * Action triggered to save an entity record's edits.
1587 *
1588 * @param {string} kind Kind of the entity.
1589 * @param {string} name Name of the entity.
1590 * @param {Object} recordId ID of the record.
1591 * @param {Object} options Saving options.
1592 */
1593
1594 const saveEditedEntityRecord = (kind, name, recordId, options) => async ({
1595 select,
1596 dispatch
1597 }) => {
1598 if (!select.hasEditsForEntityRecord(kind, name, recordId)) {
1599 return;
1600 }
1601
1602 const edits = select.getEntityRecordNonTransientEdits(kind, name, recordId);
1603 const record = {
1604 id: recordId,
1605 ...edits
1606 };
1607 return await dispatch.saveEntityRecord(kind, name, record, options);
1608 };
1609 /**
1610 * Action triggered to save only specified properties for the entity.
1611 *
1612 * @param {string} kind Kind of the entity.
1613 * @param {string} name Name of the entity.
1614 * @param {Object} recordId ID of the record.
1615 * @param {Array} itemsToSave List of entity properties to save.
1616 * @param {Object} options Saving options.
1617 */
1618
1619 const __experimentalSaveSpecifiedEntityEdits = (kind, name, recordId, itemsToSave, options) => async ({
1620 select,
1621 dispatch
1622 }) => {
1623 if (!select.hasEditsForEntityRecord(kind, name, recordId)) {
1624 return;
1625 }
1626
1627 const edits = select.getEntityRecordNonTransientEdits(kind, name, recordId);
1628 const editsToSave = {};
1629
1630 for (const edit in edits) {
1631 if (itemsToSave.some(item => item === edit)) {
1632 editsToSave[edit] = edits[edit];
1633 }
1634 }
1635
1636 return await dispatch.saveEntityRecord(kind, name, editsToSave, options);
1637 };
1638 /**
1639 * Returns an action object used in signalling that Upload permissions have been received.
1640 *
1641 * @param {boolean} hasUploadPermissions Does the user have permission to upload files?
1642 *
1643 * @return {Object} Action object.
1644 */
1645
1646 function receiveUploadPermissions(hasUploadPermissions) {
1647 return {
1648 type: 'RECEIVE_USER_PERMISSION',
1649 key: 'create/media',
1650 isAllowed: hasUploadPermissions
1651 };
1652 }
1653 /**
1654 * Returns an action object used in signalling that the current user has
1655 * permission to perform an action on a REST resource.
1656 *
1657 * @param {string} key A key that represents the action and REST resource.
1658 * @param {boolean} isAllowed Whether or not the user can perform the action.
1659 *
1660 * @return {Object} Action object.
1661 */
1662
1663 function receiveUserPermission(key, isAllowed) {
1664 return {
1665 type: 'RECEIVE_USER_PERMISSION',
1666 key,
1667 isAllowed
1668 };
1669 }
1670 /**
1671 * Returns an action object used in signalling that the autosaves for a
1672 * post have been received.
1673 *
1674 * @param {number} postId The id of the post that is parent to the autosave.
1675 * @param {Array|Object} autosaves An array of autosaves or singular autosave object.
1676 *
1677 * @return {Object} Action object.
1678 */
1679
1680 function receiveAutosaves(postId, autosaves) {
1681 return {
1682 type: 'RECEIVE_AUTOSAVES',
1683 postId,
1684 autosaves: (0,external_lodash_namespaceObject.castArray)(autosaves)
1685 };
1686 }
1687 //# sourceMappingURL=actions.js.map
1688 ;// CONCATENATED MODULE: ./packages/core-data/build-module/entities.js
1689 /**
1690 * External dependencies
1691 */
1692
1693 /**
1694 * WordPress dependencies
1695 */
1696
1697
1698
1699 /**
1700 * Internal dependencies
1701 */
1702
1703
1704 const DEFAULT_ENTITY_KEY = 'id';
1705 const POST_RAW_ATTRIBUTES = ['title', 'excerpt', 'content'];
1706 const defaultEntities = [{
1707 label: (0,external_wp_i18n_namespaceObject.__)('Base'),
1708 name: '__unstableBase',
1709 kind: 'root',
1710 baseURL: ''
1711 }, {
1712 label: (0,external_wp_i18n_namespaceObject.__)('Site'),
1713 name: 'site',
1714 kind: 'root',
1715 baseURL: '/wp/v2/settings',
1716 getTitle: record => {
1717 return (0,external_lodash_namespaceObject.get)(record, ['title'], (0,external_wp_i18n_namespaceObject.__)('Site Title'));
1718 }
1719 }, {
1720 label: (0,external_wp_i18n_namespaceObject.__)('Post Type'),
1721 name: 'postType',
1722 kind: 'root',
1723 key: 'slug',
1724 baseURL: '/wp/v2/types',
1725 baseURLParams: {
1726 context: 'edit'
1727 },
1728 rawAttributes: POST_RAW_ATTRIBUTES
1729 }, {
1730 name: 'media',
1731 kind: 'root',
1732 baseURL: '/wp/v2/media',
1733 baseURLParams: {
1734 context: 'edit'
1735 },
1736 plural: 'mediaItems',
1737 label: (0,external_wp_i18n_namespaceObject.__)('Media')
1738 }, {
1739 name: 'taxonomy',
1740 kind: 'root',
1741 key: 'slug',
1742 baseURL: '/wp/v2/taxonomies',
1743 baseURLParams: {
1744 context: 'edit'
1745 },
1746 plural: 'taxonomies',
1747 label: (0,external_wp_i18n_namespaceObject.__)('Taxonomy')
1748 }, {
1749 name: 'sidebar',
1750 kind: 'root',
1751 baseURL: '/wp/v2/sidebars',
1752 plural: 'sidebars',
1753 transientEdits: {
1754 blocks: true
1755 },
1756 label: (0,external_wp_i18n_namespaceObject.__)('Widget areas')
1757 }, {
1758 name: 'widget',
1759 kind: 'root',
1760 baseURL: '/wp/v2/widgets',
1761 baseURLParams: {
1762 context: 'edit'
1763 },
1764 plural: 'widgets',
1765 transientEdits: {
1766 blocks: true
1767 },
1768 label: (0,external_wp_i18n_namespaceObject.__)('Widgets')
1769 }, {
1770 name: 'widgetType',
1771 kind: 'root',
1772 baseURL: '/wp/v2/widget-types',
1773 baseURLParams: {
1774 context: 'edit'
1775 },
1776 plural: 'widgetTypes',
1777 label: (0,external_wp_i18n_namespaceObject.__)('Widget types')
1778 }, {
1779 label: (0,external_wp_i18n_namespaceObject.__)('User'),
1780 name: 'user',
1781 kind: 'root',
1782 baseURL: '/wp/v2/users',
1783 baseURLParams: {
1784 context: 'edit'
1785 },
1786 plural: 'users'
1787 }, {
1788 name: 'comment',
1789 kind: 'root',
1790 baseURL: '/wp/v2/comments',
1791 baseURLParams: {
1792 context: 'edit'
1793 },
1794 plural: 'comments',
1795 label: (0,external_wp_i18n_namespaceObject.__)('Comment')
1796 }, {
1797 name: 'menu',
1798 kind: 'root',
1799 baseURL: '/__experimental/menus',
1800 baseURLParams: {
1801 context: 'edit'
1802 },
1803 plural: 'menus',
1804 label: (0,external_wp_i18n_namespaceObject.__)('Menu')
1805 }, {
1806 name: 'menuItem',
1807 kind: 'root',
1808 baseURL: '/__experimental/menu-items',
1809 baseURLParams: {
1810 context: 'edit'
1811 },
1812 plural: 'menuItems',
1813 label: (0,external_wp_i18n_namespaceObject.__)('Menu Item'),
1814 rawAttributes: ['title', 'content']
1815 }, {
1816 name: 'menuLocation',
1817 kind: 'root',
1818 baseURL: '/__experimental/menu-locations',
1819 baseURLParams: {
1820 context: 'edit'
1821 },
1822 plural: 'menuLocations',
1823 label: (0,external_wp_i18n_namespaceObject.__)('Menu Location'),
1824 key: 'name'
1825 }];
1826 const kinds = [{
1827 name: 'postType',
1828 loadEntities: loadPostTypeEntities
1829 }, {
1830 name: 'taxonomy',
1831 loadEntities: loadTaxonomyEntities
1832 }];
1833 /**
1834 * Returns a function to be used to retrieve extra edits to apply before persisting a post type.
1835 *
1836 * @param {Object} persistedRecord Already persisted Post
1837 * @param {Object} edits Edits.
1838 * @return {Object} Updated edits.
1839 */
1840
1841 const prePersistPostType = (persistedRecord, edits) => {
1842 const newEdits = {};
1843
1844 if ((persistedRecord === null || persistedRecord === void 0 ? void 0 : persistedRecord.status) === 'auto-draft') {
1845 // Saving an auto-draft should create a draft by default.
1846 if (!edits.status && !newEdits.status) {
1847 newEdits.status = 'draft';
1848 } // Fix the auto-draft default title.
1849
1850
1851 if ((!edits.title || edits.title === 'Auto Draft') && !newEdits.title && (!(persistedRecord !== null && persistedRecord !== void 0 && persistedRecord.title) || (persistedRecord === null || persistedRecord === void 0 ? void 0 : persistedRecord.title) === 'Auto Draft')) {
1852 newEdits.title = '';
1853 }
1854 }
1855
1856 return newEdits;
1857 };
1858 /**
1859 * Returns the list of post type entities.
1860 *
1861 * @return {Promise} Entities promise
1862 */
1863
1864 async function loadPostTypeEntities() {
1865 const postTypes = await external_wp_apiFetch_default()({
1866 path: '/wp/v2/types?context=edit'
1867 });
1868 return (0,external_lodash_namespaceObject.map)(postTypes, (postType, name) => {
1869 const isTemplate = ['wp_template', 'wp_template_part'].includes(name);
1870 return {
1871 kind: 'postType',
1872 baseURL: '/wp/v2/' + postType.rest_base,
1873 baseURLParams: {
1874 context: 'edit'
1875 },
1876 name,
1877 label: postType.labels.singular_name,
1878 transientEdits: {
1879 blocks: true,
1880 selection: true
1881 },
1882 mergedEdits: {
1883 meta: true
1884 },
1885 rawAttributes: POST_RAW_ATTRIBUTES,
1886 getTitle: record => {
1887 var _record$title;
1888
1889 return (record === null || record === void 0 ? void 0 : (_record$title = record.title) === null || _record$title === void 0 ? void 0 : _record$title.rendered) || (record === null || record === void 0 ? void 0 : record.title) || (isTemplate ? (0,external_lodash_namespaceObject.startCase)(record.slug) : String(record.id));
1890 },
1891 __unstablePrePersist: isTemplate ? undefined : prePersistPostType,
1892 __unstable_rest_base: postType.rest_base
1893 };
1894 });
1895 }
1896 /**
1897 * Returns the list of the taxonomies entities.
1898 *
1899 * @return {Promise} Entities promise
1900 */
1901
1902
1903 async function loadTaxonomyEntities() {
1904 const taxonomies = await external_wp_apiFetch_default()({
1905 path: '/wp/v2/taxonomies?context=edit'
1906 });
1907 return (0,external_lodash_namespaceObject.map)(taxonomies, (taxonomy, name) => {
1908 return {
1909 kind: 'taxonomy',
1910 baseURL: '/wp/v2/' + taxonomy.rest_base,
1911 baseURLParams: {
1912 context: 'edit'
1913 },
1914 name,
1915 label: taxonomy.labels.singular_name
1916 };
1917 });
1918 }
1919 /**
1920 * Returns the entity's getter method name given its kind and name.
1921 *
1922 * @param {string} kind Entity kind.
1923 * @param {string} name Entity name.
1924 * @param {string} prefix Function prefix.
1925 * @param {boolean} usePlural Whether to use the plural form or not.
1926 *
1927 * @return {string} Method name
1928 */
1929
1930
1931 const getMethodName = (kind, name, prefix = 'get', usePlural = false) => {
1932 const entity = (0,external_lodash_namespaceObject.find)(defaultEntities, {
1933 kind,
1934 name
1935 });
1936 const kindPrefix = kind === 'root' ? '' : (0,external_lodash_namespaceObject.upperFirst)((0,external_lodash_namespaceObject.camelCase)(kind));
1937 const nameSuffix = (0,external_lodash_namespaceObject.upperFirst)((0,external_lodash_namespaceObject.camelCase)(name)) + (usePlural ? 's' : '');
1938 const suffix = usePlural && entity.plural ? (0,external_lodash_namespaceObject.upperFirst)((0,external_lodash_namespaceObject.camelCase)(entity.plural)) : nameSuffix;
1939 return `${prefix}${kindPrefix}${suffix}`;
1940 };
1941 /**
1942 * Loads the kind entities into the store.
1943 *
1944 * @param {string} kind Kind
1945 *
1946 * @return {Array} Entities
1947 */
1948
1949 const getKindEntities = kind => async ({
1950 select,
1951 dispatch
1952 }) => {
1953 let entities = select.getEntitiesByKind(kind);
1954
1955 if (entities && entities.length !== 0) {
1956 return entities;
1957 }
1958
1959 const kindConfig = (0,external_lodash_namespaceObject.find)(kinds, {
1960 name: kind
1961 });
1962
1963 if (!kindConfig) {
1964 return [];
1965 }
1966
1967 entities = await kindConfig.loadEntities();
1968 dispatch(addEntities(entities));
1969 return entities;
1970 };
1971 //# sourceMappingURL=entities.js.map
1972 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/get-normalized-comma-separable.js
1973 /**
1974 * Given a value which can be specified as one or the other of a comma-separated
1975 * string or an array, returns a value normalized to an array of strings, or
1976 * null if the value cannot be interpreted as either.
1977 *
1978 * @param {string|string[]|*} value
1979 *
1980 * @return {?(string[])} Normalized field value.
1981 */
1982 function getNormalizedCommaSeparable(value) {
1983 if (typeof value === 'string') {
1984 return value.split(',');
1985 } else if (Array.isArray(value)) {
1986 return value;
1987 }
1988
1989 return null;
1990 }
1991
1992 /* harmony default export */ var get_normalized_comma_separable = (getNormalizedCommaSeparable);
1993 //# sourceMappingURL=get-normalized-comma-separable.js.map
1994 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/with-weak-map-cache.js
1995 /**
1996 * External dependencies
1997 */
1998
1999 /**
2000 * Given a function, returns an enhanced function which caches the result and
2001 * tracks in WeakMap. The result is only cached if the original function is
2002 * passed a valid object-like argument (requirement for WeakMap key).
2003 *
2004 * @param {Function} fn Original function.
2005 *
2006 * @return {Function} Enhanced caching function.
2007 */
2008
2009 function withWeakMapCache(fn) {
2010 const cache = new WeakMap();
2011 return key => {
2012 let value;
2013
2014 if (cache.has(key)) {
2015 value = cache.get(key);
2016 } else {
2017 value = fn(key); // Can reach here if key is not valid for WeakMap, since `has`
2018 // will return false for invalid key. Since `set` will throw,
2019 // ensure that key is valid before setting into cache.
2020
2021 if ((0,external_lodash_namespaceObject.isObjectLike)(key)) {
2022 cache.set(key, value);
2023 }
2024 }
2025
2026 return value;
2027 };
2028 }
2029
2030 /* harmony default export */ var with_weak_map_cache = (withWeakMapCache);
2031 //# sourceMappingURL=with-weak-map-cache.js.map
2032 ;// CONCATENATED MODULE: ./packages/core-data/build-module/queried-data/get-query-parts.js
2033 /**
2034 * WordPress dependencies
2035 */
2036
2037 /**
2038 * Internal dependencies
2039 */
2040
2041
2042 /**
2043 * An object of properties describing a specific query.
2044 *
2045 * @typedef {Object} WPQueriedDataQueryParts
2046 *
2047 * @property {number} page The query page (1-based index, default 1).
2048 * @property {number} perPage Items per page for query (default 10).
2049 * @property {string} stableKey An encoded stable string of all non-
2050 * pagination, non-fields query parameters.
2051 * @property {?(string[])} fields Target subset of fields to derive from
2052 * item objects.
2053 * @property {?(number[])} include Specific item IDs to include.
2054 */
2055
2056 /**
2057 * Given a query object, returns an object of parts, including pagination
2058 * details (`page` and `perPage`, or default values). All other properties are
2059 * encoded into a stable (idempotent) `stableKey` value.
2060 *
2061 * @param {Object} query Optional query object.
2062 *
2063 * @return {WPQueriedDataQueryParts} Query parts.
2064 */
2065
2066 function getQueryParts(query) {
2067 /**
2068 * @type {WPQueriedDataQueryParts}
2069 */
2070 const parts = {
2071 stableKey: '',
2072 page: 1,
2073 perPage: 10,
2074 fields: null,
2075 include: null,
2076 context: 'default'
2077 }; // Ensure stable key by sorting keys. Also more efficient for iterating.
2078
2079 const keys = Object.keys(query).sort();
2080
2081 for (let i = 0; i < keys.length; i++) {
2082 const key = keys[i];
2083 let value = query[key];
2084
2085 switch (key) {
2086 case 'page':
2087 parts[key] = Number(value);
2088 break;
2089
2090 case 'per_page':
2091 parts.perPage = Number(value);
2092 break;
2093
2094 case 'context':
2095 parts.context = value;
2096 break;
2097
2098 default:
2099 // While in theory, we could exclude "_fields" from the stableKey
2100 // because two request with different fields have the same results
2101 // We're not able to ensure that because the server can decide to omit
2102 // fields from the response even if we explicitely asked for it.
2103 // Example: Asking for titles in posts without title support.
2104 if (key === '_fields') {
2105 parts.fields = get_normalized_comma_separable(value); // Make sure to normalize value for `stableKey`
2106
2107 value = parts.fields.join();
2108 } // Two requests with different include values cannot have same results.
2109
2110
2111 if (key === 'include') {
2112 parts.include = get_normalized_comma_separable(value).map(Number); // Normalize value for `stableKey`.
2113
2114 value = parts.include.join();
2115 } // While it could be any deterministic string, for simplicity's
2116 // sake mimic querystring encoding for stable key.
2117 //
2118 // TODO: For consistency with PHP implementation, addQueryArgs
2119 // should accept a key value pair, which may optimize its
2120 // implementation for our use here, vs. iterating an object
2121 // with only a single key.
2122
2123
2124 parts.stableKey += (parts.stableKey ? '&' : '') + (0,external_wp_url_namespaceObject.addQueryArgs)('', {
2125 [key]: value
2126 }).slice(1);
2127 }
2128 }
2129
2130 return parts;
2131 }
2132 /* harmony default export */ var get_query_parts = (with_weak_map_cache(getQueryParts));
2133 //# sourceMappingURL=get-query-parts.js.map
2134 ;// CONCATENATED MODULE: ./packages/core-data/build-module/queried-data/reducer.js
2135 /**
2136 * External dependencies
2137 */
2138
2139 /**
2140 * WordPress dependencies
2141 */
2142
2143
2144 /**
2145 * Internal dependencies
2146 */
2147
2148
2149
2150
2151
2152 function getContextFromAction(action) {
2153 const {
2154 query
2155 } = action;
2156
2157 if (!query) {
2158 return 'default';
2159 }
2160
2161 const queryParts = get_query_parts(query);
2162 return queryParts.context;
2163 }
2164 /**
2165 * Returns a merged array of item IDs, given details of the received paginated
2166 * items. The array is sparse-like with `undefined` entries where holes exist.
2167 *
2168 * @param {?Array<number>} itemIds Original item IDs (default empty array).
2169 * @param {number[]} nextItemIds Item IDs to merge.
2170 * @param {number} page Page of items merged.
2171 * @param {number} perPage Number of items per page.
2172 *
2173 * @return {number[]} Merged array of item IDs.
2174 */
2175
2176
2177 function getMergedItemIds(itemIds, nextItemIds, page, perPage) {
2178 const receivedAllIds = page === 1 && perPage === -1;
2179
2180 if (receivedAllIds) {
2181 return nextItemIds;
2182 }
2183
2184 const nextItemIdsStartIndex = (page - 1) * perPage; // If later page has already been received, default to the larger known
2185 // size of the existing array, else calculate as extending the existing.
2186
2187 const size = Math.max(itemIds.length, nextItemIdsStartIndex + nextItemIds.length); // Preallocate array since size is known.
2188
2189 const mergedItemIds = new Array(size);
2190
2191 for (let i = 0; i < size; i++) {
2192 // Preserve existing item ID except for subset of range of next items.
2193 const isInNextItemsRange = i >= nextItemIdsStartIndex && i < nextItemIdsStartIndex + nextItemIds.length;
2194 mergedItemIds[i] = isInNextItemsRange ? nextItemIds[i - nextItemIdsStartIndex] : itemIds[i];
2195 }
2196
2197 return mergedItemIds;
2198 }
2199 /**
2200 * Reducer tracking items state, keyed by ID. Items are assumed to be normal,
2201 * where identifiers are common across all queries.
2202 *
2203 * @param {Object} state Current state.
2204 * @param {Object} action Dispatched action.
2205 *
2206 * @return {Object} Next state.
2207 */
2208
2209 function items(state = {}, action) {
2210 switch (action.type) {
2211 case 'RECEIVE_ITEMS':
2212 {
2213 const context = getContextFromAction(action);
2214 const key = action.key || DEFAULT_ENTITY_KEY;
2215 return { ...state,
2216 [context]: { ...state[context],
2217 ...action.items.reduce((accumulator, value) => {
2218 var _state$context;
2219
2220 const itemId = value[key];
2221 accumulator[itemId] = conservativeMapItem(state === null || state === void 0 ? void 0 : (_state$context = state[context]) === null || _state$context === void 0 ? void 0 : _state$context[itemId], value);
2222 return accumulator;
2223 }, {})
2224 }
2225 };
2226 }
2227
2228 case 'REMOVE_ITEMS':
2229 return (0,external_lodash_namespaceObject.mapValues)(state, contextState => (0,external_lodash_namespaceObject.omit)(contextState, action.itemIds));
2230 }
2231
2232 return state;
2233 }
2234 /**
2235 * Reducer tracking item completeness, keyed by ID. A complete item is one for
2236 * which all fields are known. This is used in supporting `_fields` queries,
2237 * where not all properties associated with an entity are necessarily returned.
2238 * In such cases, completeness is used as an indication of whether it would be
2239 * safe to use queried data for a non-`_fields`-limited request.
2240 *
2241 * @param {Object<string,boolean>} state Current state.
2242 * @param {Object} action Dispatched action.
2243 *
2244 * @return {Object<string,boolean>} Next state.
2245 */
2246
2247 function itemIsComplete(state = {}, action) {
2248 switch (action.type) {
2249 case 'RECEIVE_ITEMS':
2250 {
2251 const context = getContextFromAction(action);
2252 const {
2253 query,
2254 key = DEFAULT_ENTITY_KEY
2255 } = action; // An item is considered complete if it is received without an associated
2256 // fields query. Ideally, this would be implemented in such a way where the
2257 // complete aggregate of all fields would satisfy completeness. Since the
2258 // fields are not consistent across all entity types, this would require
2259 // introspection on the REST schema for each entity to know which fields
2260 // compose a complete item for that entity.
2261
2262 const queryParts = query ? get_query_parts(query) : {};
2263 const isCompleteQuery = !query || !Array.isArray(queryParts.fields);
2264 return { ...state,
2265 [context]: { ...state[context],
2266 ...action.items.reduce((result, item) => {
2267 var _state$context2;
2268
2269 const itemId = item[key]; // Defer to completeness if already assigned. Technically the
2270 // data may be outdated if receiving items for a field subset.
2271
2272 result[itemId] = (state === null || state === void 0 ? void 0 : (_state$context2 = state[context]) === null || _state$context2 === void 0 ? void 0 : _state$context2[itemId]) || isCompleteQuery;
2273 return result;
2274 }, {})
2275 }
2276 };
2277 }
2278
2279 case 'REMOVE_ITEMS':
2280 return (0,external_lodash_namespaceObject.mapValues)(state, contextState => (0,external_lodash_namespaceObject.omit)(contextState, action.itemIds));
2281 }
2282
2283 return state;
2284 }
2285 /**
2286 * Reducer tracking queries state, keyed by stable query key. Each reducer
2287 * query object includes `itemIds` and `requestingPageByPerPage`.
2288 *
2289 * @param {Object} state Current state.
2290 * @param {Object} action Dispatched action.
2291 *
2292 * @return {Object} Next state.
2293 */
2294
2295 const receiveQueries = (0,external_lodash_namespaceObject.flowRight)([// Limit to matching action type so we don't attempt to replace action on
2296 // an unhandled action.
2297 if_matching_action(action => 'query' in action), // Inject query parts into action for use both in `onSubKey` and reducer.
2298 replace_action(action => {
2299 // `ifMatchingAction` still passes on initialization, where state is
2300 // undefined and a query is not assigned. Avoid attempting to parse
2301 // parts. `onSubKey` will omit by lack of `stableKey`.
2302 if (action.query) {
2303 return { ...action,
2304 ...get_query_parts(action.query)
2305 };
2306 }
2307
2308 return action;
2309 }), on_sub_key('context'), // Queries shape is shared, but keyed by query `stableKey` part. Original
2310 // reducer tracks only a single query object.
2311 on_sub_key('stableKey')])((state = null, action) => {
2312 const {
2313 type,
2314 page,
2315 perPage,
2316 key = DEFAULT_ENTITY_KEY
2317 } = action;
2318
2319 if (type !== 'RECEIVE_ITEMS') {
2320 return state;
2321 }
2322
2323 return getMergedItemIds(state || [], (0,external_lodash_namespaceObject.map)(action.items, key), page, perPage);
2324 });
2325 /**
2326 * Reducer tracking queries state.
2327 *
2328 * @param {Object} state Current state.
2329 * @param {Object} action Dispatched action.
2330 *
2331 * @return {Object} Next state.
2332 */
2333
2334 const queries = (state = {}, action) => {
2335 switch (action.type) {
2336 case 'RECEIVE_ITEMS':
2337 return receiveQueries(state, action);
2338
2339 case 'REMOVE_ITEMS':
2340 const removedItems = action.itemIds.reduce((result, itemId) => {
2341 result[itemId] = true;
2342 return result;
2343 }, {});
2344 return (0,external_lodash_namespaceObject.mapValues)(state, contextQueries => {
2345 return (0,external_lodash_namespaceObject.mapValues)(contextQueries, queryItems => {
2346 return (0,external_lodash_namespaceObject.filter)(queryItems, queryId => {
2347 return !removedItems[queryId];
2348 });
2349 });
2350 });
2351
2352 default:
2353 return state;
2354 }
2355 };
2356
2357 /* harmony default export */ var reducer = ((0,external_wp_data_namespaceObject.combineReducers)({
2358 items,
2359 itemIsComplete,
2360 queries
2361 }));
2362 //# sourceMappingURL=reducer.js.map
2363 ;// CONCATENATED MODULE: ./packages/core-data/build-module/reducer.js
2364 /**
2365 * External dependencies
2366 */
2367
2368 /**
2369 * WordPress dependencies
2370 */
2371
2372
2373
2374 /**
2375 * Internal dependencies
2376 */
2377
2378
2379
2380
2381 /**
2382 * Reducer managing terms state. Keyed by taxonomy slug, the value is either
2383 * undefined (if no request has been made for given taxonomy), null (if a
2384 * request is in-flight for given taxonomy), or the array of terms for the
2385 * taxonomy.
2386 *
2387 * @param {Object} state Current state.
2388 * @param {Object} action Dispatched action.
2389 *
2390 * @return {Object} Updated state.
2391 */
2392
2393 function terms(state = {}, action) {
2394 switch (action.type) {
2395 case 'RECEIVE_TERMS':
2396 return { ...state,
2397 [action.taxonomy]: action.terms
2398 };
2399 }
2400
2401 return state;
2402 }
2403 /**
2404 * Reducer managing authors state. Keyed by id.
2405 *
2406 * @param {Object} state Current state.
2407 * @param {Object} action Dispatched action.
2408 *
2409 * @return {Object} Updated state.
2410 */
2411
2412 function users(state = {
2413 byId: {},
2414 queries: {}
2415 }, action) {
2416 switch (action.type) {
2417 case 'RECEIVE_USER_QUERY':
2418 return {
2419 byId: { ...state.byId,
2420 ...(0,external_lodash_namespaceObject.keyBy)(action.users, 'id')
2421 },
2422 queries: { ...state.queries,
2423 [action.queryID]: (0,external_lodash_namespaceObject.map)(action.users, user => user.id)
2424 }
2425 };
2426 }
2427
2428 return state;
2429 }
2430 /**
2431 * Reducer managing current user state.
2432 *
2433 * @param {Object} state Current state.
2434 * @param {Object} action Dispatched action.
2435 *
2436 * @return {Object} Updated state.
2437 */
2438
2439 function currentUser(state = {}, action) {
2440 switch (action.type) {
2441 case 'RECEIVE_CURRENT_USER':
2442 return action.currentUser;
2443 }
2444
2445 return state;
2446 }
2447 /**
2448 * Reducer managing taxonomies.
2449 *
2450 * @param {Object} state Current state.
2451 * @param {Object} action Dispatched action.
2452 *
2453 * @return {Object} Updated state.
2454 */
2455
2456 function taxonomies(state = [], action) {
2457 switch (action.type) {
2458 case 'RECEIVE_TAXONOMIES':
2459 return action.taxonomies;
2460 }
2461
2462 return state;
2463 }
2464 /**
2465 * Reducer managing the current theme.
2466 *
2467 * @param {string} state Current state.
2468 * @param {Object} action Dispatched action.
2469 *
2470 * @return {string} Updated state.
2471 */
2472
2473 function currentTheme(state = undefined, action) {
2474 switch (action.type) {
2475 case 'RECEIVE_CURRENT_THEME':
2476 return action.currentTheme.stylesheet;
2477 }
2478
2479 return state;
2480 }
2481 /**
2482 * Reducer managing installed themes.
2483 *
2484 * @param {Object} state Current state.
2485 * @param {Object} action Dispatched action.
2486 *
2487 * @return {Object} Updated state.
2488 */
2489
2490 function themes(state = {}, action) {
2491 switch (action.type) {
2492 case 'RECEIVE_CURRENT_THEME':
2493 return { ...state,
2494 [action.currentTheme.stylesheet]: action.currentTheme
2495 };
2496 }
2497
2498 return state;
2499 }
2500 /**
2501 * Reducer managing theme supports data.
2502 *
2503 * @param {Object} state Current state.
2504 * @param {Object} action Dispatched action.
2505 *
2506 * @return {Object} Updated state.
2507 */
2508
2509 function themeSupports(state = {}, action) {
2510 switch (action.type) {
2511 case 'RECEIVE_THEME_SUPPORTS':
2512 return { ...state,
2513 ...action.themeSupports
2514 };
2515 }
2516
2517 return state;
2518 }
2519 /**
2520 * Higher Order Reducer for a given entity config. It supports:
2521 *
2522 * - Fetching
2523 * - Editing
2524 * - Saving
2525 *
2526 * @param {Object} entityConfig Entity config.
2527 *
2528 * @return {Function} Reducer.
2529 */
2530
2531 function entity(entityConfig) {
2532 return (0,external_lodash_namespaceObject.flowRight)([// Limit to matching action type so we don't attempt to replace action on
2533 // an unhandled action.
2534 if_matching_action(action => action.name && action.kind && action.name === entityConfig.name && action.kind === entityConfig.kind), // Inject the entity config into the action.
2535 replace_action(action => {
2536 return { ...action,
2537 key: entityConfig.key || DEFAULT_ENTITY_KEY
2538 };
2539 })])((0,external_wp_data_namespaceObject.combineReducers)({
2540 queriedData: reducer,
2541 edits: (state = {}, action) => {
2542 var _action$query$context, _action$query;
2543
2544 switch (action.type) {
2545 case 'RECEIVE_ITEMS':
2546 const context = (_action$query$context = action === null || action === void 0 ? void 0 : (_action$query = action.query) === null || _action$query === void 0 ? void 0 : _action$query.context) !== null && _action$query$context !== void 0 ? _action$query$context : 'default';
2547
2548 if (context !== 'default') {
2549 return state;
2550 }
2551
2552 const nextState = { ...state
2553 };
2554
2555 for (const record of action.items) {
2556 const recordId = record[action.key];
2557 const edits = nextState[recordId];
2558
2559 if (!edits) {
2560 continue;
2561 }
2562
2563 const nextEdits = Object.keys(edits).reduce((acc, key) => {
2564 // If the edited value is still different to the persisted value,
2565 // keep the edited value in edits.
2566 if ( // Edits are the "raw" attribute values, but records may have
2567 // objects with more properties, so we use `get` here for the
2568 // comparison.
2569 !(0,external_lodash_namespaceObject.isEqual)(edits[key], (0,external_lodash_namespaceObject.get)(record[key], 'raw', record[key])) && ( // Sometimes the server alters the sent value which means
2570 // we need to also remove the edits before the api request.
2571 !action.persistedEdits || !(0,external_lodash_namespaceObject.isEqual)(edits[key], action.persistedEdits[key]))) {
2572 acc[key] = edits[key];
2573 }
2574
2575 return acc;
2576 }, {});
2577
2578 if (Object.keys(nextEdits).length) {
2579 nextState[recordId] = nextEdits;
2580 } else {
2581 delete nextState[recordId];
2582 }
2583 }
2584
2585 return nextState;
2586
2587 case 'EDIT_ENTITY_RECORD':
2588 const nextEdits = { ...state[action.recordId],
2589 ...action.edits
2590 };
2591 Object.keys(nextEdits).forEach(key => {
2592 // Delete cleared edits so that the properties
2593 // are not considered dirty.
2594 if (nextEdits[key] === undefined) {
2595 delete nextEdits[key];
2596 }
2597 });
2598 return { ...state,
2599 [action.recordId]: nextEdits
2600 };
2601 }
2602
2603 return state;
2604 },
2605 saving: (state = {}, action) => {
2606 switch (action.type) {
2607 case 'SAVE_ENTITY_RECORD_START':
2608 case 'SAVE_ENTITY_RECORD_FINISH':
2609 return { ...state,
2610 [action.recordId]: {
2611 pending: action.type === 'SAVE_ENTITY_RECORD_START',
2612 error: action.error,
2613 isAutosave: action.isAutosave
2614 }
2615 };
2616 }
2617
2618 return state;
2619 },
2620 deleting: (state = {}, action) => {
2621 switch (action.type) {
2622 case 'DELETE_ENTITY_RECORD_START':
2623 case 'DELETE_ENTITY_RECORD_FINISH':
2624 return { ...state,
2625 [action.recordId]: {
2626 pending: action.type === 'DELETE_ENTITY_RECORD_START',
2627 error: action.error
2628 }
2629 };
2630 }
2631
2632 return state;
2633 }
2634 }));
2635 }
2636 /**
2637 * Reducer keeping track of the registered entities.
2638 *
2639 * @param {Object} state Current state.
2640 * @param {Object} action Dispatched action.
2641 *
2642 * @return {Object} Updated state.
2643 */
2644
2645
2646 function entitiesConfig(state = defaultEntities, action) {
2647 switch (action.type) {
2648 case 'ADD_ENTITIES':
2649 return [...state, ...action.entities];
2650 }
2651
2652 return state;
2653 }
2654 /**
2655 * Reducer keeping track of the registered entities config and data.
2656 *
2657 * @param {Object} state Current state.
2658 * @param {Object} action Dispatched action.
2659 *
2660 * @return {Object} Updated state.
2661 */
2662
2663 const entities = (state = {}, action) => {
2664 const newConfig = entitiesConfig(state.config, action); // Generates a dynamic reducer for the entities
2665
2666 let entitiesDataReducer = state.reducer;
2667
2668 if (!entitiesDataReducer || newConfig !== state.config) {
2669 const entitiesByKind = (0,external_lodash_namespaceObject.groupBy)(newConfig, 'kind');
2670 entitiesDataReducer = (0,external_wp_data_namespaceObject.combineReducers)(Object.entries(entitiesByKind).reduce((memo, [kind, subEntities]) => {
2671 const kindReducer = (0,external_wp_data_namespaceObject.combineReducers)(subEntities.reduce((kindMemo, entityConfig) => ({ ...kindMemo,
2672 [entityConfig.name]: entity(entityConfig)
2673 }), {}));
2674 memo[kind] = kindReducer;
2675 return memo;
2676 }, {}));
2677 }
2678
2679 const newData = entitiesDataReducer(state.data, action);
2680
2681 if (newData === state.data && newConfig === state.config && entitiesDataReducer === state.reducer) {
2682 return state;
2683 }
2684
2685 return {
2686 reducer: entitiesDataReducer,
2687 data: newData,
2688 config: newConfig
2689 };
2690 };
2691 /**
2692 * Reducer keeping track of entity edit undo history.
2693 *
2694 * @param {Object} state Current state.
2695 * @param {Object} action Dispatched action.
2696 *
2697 * @return {Object} Updated state.
2698 */
2699
2700 const UNDO_INITIAL_STATE = [];
2701 UNDO_INITIAL_STATE.offset = 0;
2702 let lastEditAction;
2703 function reducer_undo(state = UNDO_INITIAL_STATE, action) {
2704 switch (action.type) {
2705 case 'EDIT_ENTITY_RECORD':
2706 case 'CREATE_UNDO_LEVEL':
2707 let isCreateUndoLevel = action.type === 'CREATE_UNDO_LEVEL';
2708 const isUndoOrRedo = !isCreateUndoLevel && (action.meta.isUndo || action.meta.isRedo);
2709
2710 if (isCreateUndoLevel) {
2711 action = lastEditAction;
2712 } else if (!isUndoOrRedo) {
2713 // Don't lose the last edit cache if the new one only has transient edits.
2714 // Transient edits don't create new levels so updating the cache would make
2715 // us skip an edit later when creating levels explicitly.
2716 if (Object.keys(action.edits).some(key => !action.transientEdits[key])) {
2717 lastEditAction = action;
2718 } else {
2719 lastEditAction = { ...action,
2720 edits: { ...(lastEditAction && lastEditAction.edits),
2721 ...action.edits
2722 }
2723 };
2724 }
2725 }
2726
2727 let nextState;
2728
2729 if (isUndoOrRedo) {
2730 nextState = [...state];
2731 nextState.offset = state.offset + (action.meta.isUndo ? -1 : 1);
2732
2733 if (state.flattenedUndo) {
2734 // The first undo in a sequence of undos might happen while we have
2735 // flattened undos in state. If this is the case, we want execution
2736 // to continue as if we were creating an explicit undo level. This
2737 // will result in an extra undo level being appended with the flattened
2738 // undo values.
2739 isCreateUndoLevel = true;
2740 action = lastEditAction;
2741 } else {
2742 return nextState;
2743 }
2744 }
2745
2746 if (!action.meta.undo) {
2747 return state;
2748 } // Transient edits don't create an undo level, but are
2749 // reachable in the next meaningful edit to which they
2750 // are merged. They are defined in the entity's config.
2751
2752
2753 if (!isCreateUndoLevel && !Object.keys(action.edits).some(key => !action.transientEdits[key])) {
2754 nextState = [...state];
2755 nextState.flattenedUndo = { ...state.flattenedUndo,
2756 ...action.edits
2757 };
2758 nextState.offset = state.offset;
2759 return nextState;
2760 } // Clear potential redos, because this only supports linear history.
2761
2762
2763 nextState = nextState || state.slice(0, state.offset || undefined);
2764 nextState.offset = nextState.offset || 0;
2765 nextState.pop();
2766
2767 if (!isCreateUndoLevel) {
2768 nextState.push({
2769 kind: action.meta.undo.kind,
2770 name: action.meta.undo.name,
2771 recordId: action.meta.undo.recordId,
2772 edits: { ...state.flattenedUndo,
2773 ...action.meta.undo.edits
2774 }
2775 });
2776 } // When an edit is a function it's an optimization to avoid running some expensive operation.
2777 // We can't rely on the function references being the same so we opt out of comparing them here.
2778
2779
2780 const comparisonUndoEdits = Object.values(action.meta.undo.edits).filter(edit => typeof edit !== 'function');
2781 const comparisonEdits = Object.values(action.edits).filter(edit => typeof edit !== 'function');
2782
2783 if (!external_wp_isShallowEqual_default()(comparisonUndoEdits, comparisonEdits)) {
2784 nextState.push({
2785 kind: action.kind,
2786 name: action.name,
2787 recordId: action.recordId,
2788 edits: isCreateUndoLevel ? { ...state.flattenedUndo,
2789 ...action.edits
2790 } : action.edits
2791 });
2792 }
2793
2794 return nextState;
2795 }
2796
2797 return state;
2798 }
2799 /**
2800 * Reducer managing embed preview data.
2801 *
2802 * @param {Object} state Current state.
2803 * @param {Object} action Dispatched action.
2804 *
2805 * @return {Object} Updated state.
2806 */
2807
2808 function embedPreviews(state = {}, action) {
2809 switch (action.type) {
2810 case 'RECEIVE_EMBED_PREVIEW':
2811 const {
2812 url,
2813 preview
2814 } = action;
2815 return { ...state,
2816 [url]: preview
2817 };
2818 }
2819
2820 return state;
2821 }
2822 /**
2823 * State which tracks whether the user can perform an action on a REST
2824 * resource.
2825 *
2826 * @param {Object} state Current state.
2827 * @param {Object} action Dispatched action.
2828 *
2829 * @return {Object} Updated state.
2830 */
2831
2832 function userPermissions(state = {}, action) {
2833 switch (action.type) {
2834 case 'RECEIVE_USER_PERMISSION':
2835 return { ...state,
2836 [action.key]: action.isAllowed
2837 };
2838 }
2839
2840 return state;
2841 }
2842 /**
2843 * Reducer returning autosaves keyed by their parent's post id.
2844 *
2845 * @param {Object} state Current state.
2846 * @param {Object} action Dispatched action.
2847 *
2848 * @return {Object} Updated state.
2849 */
2850
2851 function autosaves(state = {}, action) {
2852 switch (action.type) {
2853 case 'RECEIVE_AUTOSAVES':
2854 const {
2855 postId,
2856 autosaves: autosavesData
2857 } = action;
2858 return { ...state,
2859 [postId]: autosavesData
2860 };
2861 }
2862
2863 return state;
2864 }
2865 /* harmony default export */ var build_module_reducer = ((0,external_wp_data_namespaceObject.combineReducers)({
2866 terms,
2867 users,
2868 currentTheme,
2869 currentUser,
2870 taxonomies,
2871 themes,
2872 themeSupports,
2873 entities,
2874 undo: reducer_undo,
2875 embedPreviews,
2876 userPermissions,
2877 autosaves
2878 }));
2879 //# sourceMappingURL=reducer.js.map
2880 ;// CONCATENATED MODULE: ./node_modules/rememo/es/rememo.js
2881
2882
2883 var LEAF_KEY, hasWeakMap;
2884
2885 /**
2886 * Arbitrary value used as key for referencing cache object in WeakMap tree.
2887 *
2888 * @type {Object}
2889 */
2890 LEAF_KEY = {};
2891
2892 /**
2893 * Whether environment supports WeakMap.
2894 *
2895 * @type {boolean}
2896 */
2897 hasWeakMap = typeof WeakMap !== 'undefined';
2898
2899 /**
2900 * Returns the first argument as the sole entry in an array.
2901 *
2902 * @param {*} value Value to return.
2903 *
2904 * @return {Array} Value returned as entry in array.
2905 */
2906 function arrayOf( value ) {
2907 return [ value ];
2908 }
2909
2910 /**
2911 * Returns true if the value passed is object-like, or false otherwise. A value
2912 * is object-like if it can support property assignment, e.g. object or array.
2913 *
2914 * @param {*} value Value to test.
2915 *
2916 * @return {boolean} Whether value is object-like.
2917 */
2918 function isObjectLike( value ) {
2919 return !! value && 'object' === typeof value;
2920 }
2921
2922 /**
2923 * Creates and returns a new cache object.
2924 *
2925 * @return {Object} Cache object.
2926 */
2927 function createCache() {
2928 var cache = {
2929 clear: function() {
2930 cache.head = null;
2931 },
2932 };
2933
2934 return cache;
2935 }
2936
2937 /**
2938 * Returns true if entries within the two arrays are strictly equal by
2939 * reference from a starting index.
2940 *
2941 * @param {Array} a First array.
2942 * @param {Array} b Second array.
2943 * @param {number} fromIndex Index from which to start comparison.
2944 *
2945 * @return {boolean} Whether arrays are shallowly equal.
2946 */
2947 function isShallowEqual( a, b, fromIndex ) {
2948 var i;
2949
2950 if ( a.length !== b.length ) {
2951 return false;
2952 }
2953
2954 for ( i = fromIndex; i < a.length; i++ ) {
2955 if ( a[ i ] !== b[ i ] ) {
2956 return false;
2957 }
2958 }
2959
2960 return true;
2961 }
2962
2963 /**
2964 * Returns a memoized selector function. The getDependants function argument is
2965 * called before the memoized selector and is expected to return an immutable
2966 * reference or array of references on which the selector depends for computing
2967 * its own return value. The memoize cache is preserved only as long as those
2968 * dependant references remain the same. If getDependants returns a different
2969 * reference(s), the cache is cleared and the selector value regenerated.
2970 *
2971 * @param {Function} selector Selector function.
2972 * @param {Function} getDependants Dependant getter returning an immutable
2973 * reference or array of reference used in
2974 * cache bust consideration.
2975 *
2976 * @return {Function} Memoized selector.
2977 */
2978 /* harmony default export */ function rememo(selector, getDependants ) {
2979 var rootCache, getCache;
2980
2981 // Use object source as dependant if getter not provided
2982 if ( ! getDependants ) {
2983 getDependants = arrayOf;
2984 }
2985
2986 /**
2987 * Returns the root cache. If WeakMap is supported, this is assigned to the
2988 * root WeakMap cache set, otherwise it is a shared instance of the default
2989 * cache object.
2990 *
2991 * @return {(WeakMap|Object)} Root cache object.
2992 */
2993 function getRootCache() {
2994 return rootCache;
2995 }
2996
2997 /**
2998 * Returns the cache for a given dependants array. When possible, a WeakMap
2999 * will be used to create a unique cache for each set of dependants. This
3000 * is feasible due to the nature of WeakMap in allowing garbage collection
3001 * to occur on entries where the key object is no longer referenced. Since
3002 * WeakMap requires the key to be an object, this is only possible when the
3003 * dependant is object-like. The root cache is created as a hierarchy where
3004 * each top-level key is the first entry in a dependants set, the value a
3005 * WeakMap where each key is the next dependant, and so on. This continues
3006 * so long as the dependants are object-like. If no dependants are object-
3007 * like, then the cache is shared across all invocations.
3008 *
3009 * @see isObjectLike
3010 *
3011 * @param {Array} dependants Selector dependants.
3012 *
3013 * @return {Object} Cache object.
3014 */
3015 function getWeakMapCache( dependants ) {
3016 var caches = rootCache,
3017 isUniqueByDependants = true,
3018 i, dependant, map, cache;
3019
3020 for ( i = 0; i < dependants.length; i++ ) {
3021 dependant = dependants[ i ];
3022
3023 // Can only compose WeakMap from object-like key.
3024 if ( ! isObjectLike( dependant ) ) {
3025 isUniqueByDependants = false;
3026 break;
3027 }
3028
3029 // Does current segment of cache already have a WeakMap?
3030 if ( caches.has( dependant ) ) {
3031 // Traverse into nested WeakMap.
3032 caches = caches.get( dependant );
3033 } else {
3034 // Create, set, and traverse into a new one.
3035 map = new WeakMap();
3036 caches.set( dependant, map );
3037 caches = map;
3038 }
3039 }
3040
3041 // We use an arbitrary (but consistent) object as key for the last item
3042 // in the WeakMap to serve as our running cache.
3043 if ( ! caches.has( LEAF_KEY ) ) {
3044 cache = createCache();
3045 cache.isUniqueByDependants = isUniqueByDependants;
3046 caches.set( LEAF_KEY, cache );
3047 }
3048
3049 return caches.get( LEAF_KEY );
3050 }
3051
3052 // Assign cache handler by availability of WeakMap
3053 getCache = hasWeakMap ? getWeakMapCache : getRootCache;
3054
3055 /**
3056 * Resets root memoization cache.
3057 */
3058 function clear() {
3059 rootCache = hasWeakMap ? new WeakMap() : createCache();
3060 }
3061
3062 // eslint-disable-next-line jsdoc/check-param-names
3063 /**
3064 * The augmented selector call, considering first whether dependants have
3065 * changed before passing it to underlying memoize function.
3066 *
3067 * @param {Object} source Source object for derivation.
3068 * @param {...*} extraArgs Additional arguments to pass to selector.
3069 *
3070 * @return {*} Selector result.
3071 */
3072 function callSelector( /* source, ...extraArgs */ ) {
3073 var len = arguments.length,
3074 cache, node, i, args, dependants;
3075
3076 // Create copy of arguments (avoid leaking deoptimization).
3077 args = new Array( len );
3078 for ( i = 0; i < len; i++ ) {
3079 args[ i ] = arguments[ i ];
3080 }
3081
3082 dependants = getDependants.apply( null, args );
3083 cache = getCache( dependants );
3084
3085 // If not guaranteed uniqueness by dependants (primitive type or lack
3086 // of WeakMap support), shallow compare against last dependants and, if
3087 // references have changed, destroy cache to recalculate result.
3088 if ( ! cache.isUniqueByDependants ) {
3089 if ( cache.lastDependants && ! isShallowEqual( dependants, cache.lastDependants, 0 ) ) {
3090 cache.clear();
3091 }
3092
3093 cache.lastDependants = dependants;
3094 }
3095
3096 node = cache.head;
3097 while ( node ) {
3098 // Check whether node arguments match arguments
3099 if ( ! isShallowEqual( node.args, args, 1 ) ) {
3100 node = node.next;
3101 continue;
3102 }
3103
3104 // At this point we can assume we've found a match
3105
3106 // Surface matched node to head if not already
3107 if ( node !== cache.head ) {
3108 // Adjust siblings to point to each other.
3109 node.prev.next = node.next;
3110 if ( node.next ) {
3111 node.next.prev = node.prev;
3112 }
3113
3114 node.next = cache.head;
3115 node.prev = null;
3116 cache.head.prev = node;
3117 cache.head = node;
3118 }
3119
3120 // Return immediately
3121 return node.val;
3122 }
3123
3124 // No cached value found. Continue to insertion phase:
3125
3126 node = {
3127 // Generate the result from original function
3128 val: selector.apply( null, args ),
3129 };
3130
3131 // Avoid including the source object in the cache.
3132 args[ 0 ] = null;
3133 node.args = args;
3134
3135 // Don't need to check whether node is already head, since it would
3136 // have been returned above already if it was
3137
3138 // Shift existing head down list
3139 if ( cache.head ) {
3140 cache.head.prev = node;
3141 node.next = cache.head;
3142 }
3143
3144 cache.head = node;
3145
3146 return node.val;
3147 }
3148
3149 callSelector.getDependants = getDependants;
3150 callSelector.clear = clear;
3151 clear();
3152
3153 return callSelector;
3154 }
3155
3156 ;// CONCATENATED MODULE: external ["wp","deprecated"]
3157 var external_wp_deprecated_namespaceObject = window["wp"]["deprecated"];
3158 var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject);
3159 // EXTERNAL MODULE: ./node_modules/equivalent-key-map/equivalent-key-map.js
3160 var equivalent_key_map = __webpack_require__(3909);
3161 var equivalent_key_map_default = /*#__PURE__*/__webpack_require__.n(equivalent_key_map);
3162 ;// CONCATENATED MODULE: ./packages/core-data/build-module/queried-data/selectors.js
3163 /**
3164 * External dependencies
3165 */
3166
3167
3168
3169 /**
3170 * Internal dependencies
3171 */
3172
3173
3174 /**
3175 * Cache of state keys to EquivalentKeyMap where the inner map tracks queries
3176 * to their resulting items set. WeakMap allows garbage collection on expired
3177 * state references.
3178 *
3179 * @type {WeakMap<Object,EquivalentKeyMap>}
3180 */
3181
3182 const queriedItemsCacheByState = new WeakMap();
3183 /**
3184 * Returns items for a given query, or null if the items are not known.
3185 *
3186 * @param {Object} state State object.
3187 * @param {?Object} query Optional query.
3188 *
3189 * @return {?Array} Query items.
3190 */
3191
3192 function getQueriedItemsUncached(state, query) {
3193 var _state$queries, _state$queries$contex;
3194
3195 const {
3196 stableKey,
3197 page,
3198 perPage,
3199 include,
3200 fields,
3201 context
3202 } = get_query_parts(query);
3203 let itemIds;
3204
3205 if ((_state$queries = state.queries) !== null && _state$queries !== void 0 && (_state$queries$contex = _state$queries[context]) !== null && _state$queries$contex !== void 0 && _state$queries$contex[stableKey]) {
3206 itemIds = state.queries[context][stableKey];
3207 }
3208
3209 if (!itemIds) {
3210 return null;
3211 }
3212
3213 const startOffset = perPage === -1 ? 0 : (page - 1) * perPage;
3214 const endOffset = perPage === -1 ? itemIds.length : Math.min(startOffset + perPage, itemIds.length);
3215 const items = [];
3216
3217 for (let i = startOffset; i < endOffset; i++) {
3218 var _state$items$context;
3219
3220 const itemId = itemIds[i];
3221
3222 if (Array.isArray(include) && !include.includes(itemId)) {
3223 continue;
3224 } // Having a target item ID doesn't guarantee that this object has been queried.
3225
3226
3227 if (!((_state$items$context = state.items[context]) !== null && _state$items$context !== void 0 && _state$items$context.hasOwnProperty(itemId))) {
3228 return null;
3229 }
3230
3231 const item = state.items[context][itemId];
3232 let filteredItem;
3233
3234 if (Array.isArray(fields)) {
3235 filteredItem = {};
3236
3237 for (let f = 0; f < fields.length; f++) {
3238 const field = fields[f].split('.');
3239 const value = (0,external_lodash_namespaceObject.get)(item, field);
3240 (0,external_lodash_namespaceObject.set)(filteredItem, field, value);
3241 }
3242 } else {
3243 var _state$itemIsComplete;
3244
3245 // If expecting a complete item, validate that completeness, or
3246 // otherwise abort.
3247 if (!((_state$itemIsComplete = state.itemIsComplete[context]) !== null && _state$itemIsComplete !== void 0 && _state$itemIsComplete[itemId])) {
3248 return null;
3249 }
3250
3251 filteredItem = item;
3252 }
3253
3254 items.push(filteredItem);
3255 }
3256
3257 return items;
3258 }
3259 /**
3260 * Returns items for a given query, or null if the items are not known. Caches
3261 * result both per state (by reference) and per query (by deep equality).
3262 * The caching approach is intended to be durable to query objects which are
3263 * deeply but not referentially equal, since otherwise:
3264 *
3265 * `getQueriedItems( state, {} ) !== getQueriedItems( state, {} )`
3266 *
3267 * @param {Object} state State object.
3268 * @param {?Object} query Optional query.
3269 *
3270 * @return {?Array} Query items.
3271 */
3272
3273
3274 const getQueriedItems = rememo((state, query = {}) => {
3275 let queriedItemsCache = queriedItemsCacheByState.get(state);
3276
3277 if (queriedItemsCache) {
3278 const queriedItems = queriedItemsCache.get(query);
3279
3280 if (queriedItems !== undefined) {
3281 return queriedItems;
3282 }
3283 } else {
3284 queriedItemsCache = new (equivalent_key_map_default())();
3285 queriedItemsCacheByState.set(state, queriedItemsCache);
3286 }
3287
3288 const items = getQueriedItemsUncached(state, query);
3289 queriedItemsCache.set(query, items);
3290 return items;
3291 });
3292 //# sourceMappingURL=selectors.js.map
3293 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/is-raw-attribute.js
3294 /**
3295 * Checks whether the attribute is a "raw" attribute or not.
3296 *
3297 * @param {Object} entity Entity data.
3298 * @param {string} attribute Attribute name.
3299 *
3300 * @return {boolean} Is the attribute raw
3301 */
3302 function isRawAttribute(entity, attribute) {
3303 return (entity.rawAttributes || []).includes(attribute);
3304 }
3305 //# sourceMappingURL=is-raw-attribute.js.map
3306 ;// CONCATENATED MODULE: ./packages/core-data/build-module/selectors.js
3307 /**
3308 * External dependencies
3309 */
3310
3311
3312 /**
3313 * WordPress dependencies
3314 */
3315
3316
3317
3318
3319 /**
3320 * Internal dependencies
3321 */
3322
3323
3324
3325
3326
3327 /**
3328 * Shared reference to an empty array for cases where it is important to avoid
3329 * returning a new array reference on every invocation, as in a connected or
3330 * other pure component which performs `shouldComponentUpdate` check on props.
3331 * This should be used as a last resort, since the normalized data should be
3332 * maintained by the reducer result in state.
3333 *
3334 * @type {Array}
3335 */
3336
3337 const EMPTY_ARRAY = [];
3338 /**
3339 * Returns true if a request is in progress for embed preview data, or false
3340 * otherwise.
3341 *
3342 * @param {Object} state Data state.
3343 * @param {string} url URL the preview would be for.
3344 *
3345 * @return {boolean} Whether a request is in progress for an embed preview.
3346 */
3347
3348 const isRequestingEmbedPreview = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (state, url) => {
3349 return select(STORE_NAME).isResolving('getEmbedPreview', [url]);
3350 });
3351 /**
3352 * Returns all available authors.
3353 *
3354 * @deprecated since 11.3. Callers should use `select( 'core' ).getUsers({ who: 'authors' })` instead.
3355 *
3356 * @param {Object} state Data state.
3357 * @param {Object|undefined} query Optional object of query parameters to
3358 * include with request.
3359 * @return {Array} Authors list.
3360 */
3361
3362 function getAuthors(state, query) {
3363 external_wp_deprecated_default()("select( 'core' ).getAuthors()", {
3364 since: '5.9',
3365 alternative: "select( 'core' ).getUsers({ who: 'authors' })"
3366 });
3367 const path = (0,external_wp_url_namespaceObject.addQueryArgs)('/wp/v2/users/?who=authors&per_page=100', query);
3368 return getUserQueryResults(state, path);
3369 }
3370 /**
3371 * Returns the current user.
3372 *
3373 * @param {Object} state Data state.
3374 *
3375 * @return {Object} Current user object.
3376 */
3377
3378 function getCurrentUser(state) {
3379 return state.currentUser;
3380 }
3381 /**
3382 * Returns all the users returned by a query ID.
3383 *
3384 * @param {Object} state Data state.
3385 * @param {string} queryID Query ID.
3386 *
3387 * @return {Array} Users list.
3388 */
3389
3390 const getUserQueryResults = rememo((state, queryID) => {
3391 const queryResults = state.users.queries[queryID];
3392 return (0,external_lodash_namespaceObject.map)(queryResults, id => state.users.byId[id]);
3393 }, (state, queryID) => [state.users.queries[queryID], state.users.byId]);
3394 /**
3395 * Returns whether the entities for the give kind are loaded.
3396 *
3397 * @param {Object} state Data state.
3398 * @param {string} kind Entity kind.
3399 *
3400 * @return {Array<Object>} Array of entities with config matching kind.
3401 */
3402
3403 function getEntitiesByKind(state, kind) {
3404 return (0,external_lodash_namespaceObject.filter)(state.entities.config, {
3405 kind
3406 });
3407 }
3408 /**
3409 * Returns the entity object given its kind and name.
3410 *
3411 * @param {Object} state Data state.
3412 * @param {string} kind Entity kind.
3413 * @param {string} name Entity name.
3414 *
3415 * @return {Object} Entity
3416 */
3417
3418 function getEntity(state, kind, name) {
3419 return (0,external_lodash_namespaceObject.find)(state.entities.config, {
3420 kind,
3421 name
3422 });
3423 }
3424 /**
3425 * Returns the Entity's record object by key. Returns `null` if the value is not
3426 * yet received, undefined if the value entity is known to not exist, or the
3427 * entity object if it exists and is received.
3428 *
3429 * @param {Object} state State tree
3430 * @param {string} kind Entity kind.
3431 * @param {string} name Entity name.
3432 * @param {number} key Record's key
3433 * @param {?Object} query Optional query.
3434 *
3435 * @return {Object?} Record.
3436 */
3437
3438 function getEntityRecord(state, kind, name, key, query) {
3439 var _query$context, _queriedState$items$c;
3440
3441 const queriedState = (0,external_lodash_namespaceObject.get)(state.entities.data, [kind, name, 'queriedData']);
3442
3443 if (!queriedState) {
3444 return undefined;
3445 }
3446
3447 const context = (_query$context = query === null || query === void 0 ? void 0 : query.context) !== null && _query$context !== void 0 ? _query$context : 'default';
3448
3449 if (query === undefined) {
3450 var _queriedState$itemIsC;
3451
3452 // If expecting a complete item, validate that completeness.
3453 if (!((_queriedState$itemIsC = queriedState.itemIsComplete[context]) !== null && _queriedState$itemIsC !== void 0 && _queriedState$itemIsC[key])) {
3454 return undefined;
3455 }
3456
3457 return queriedState.items[context][key];
3458 }
3459
3460 const item = (_queriedState$items$c = queriedState.items[context]) === null || _queriedState$items$c === void 0 ? void 0 : _queriedState$items$c[key];
3461
3462 if (item && query._fields) {
3463 const filteredItem = {};
3464 const fields = get_normalized_comma_separable(query._fields);
3465
3466 for (let f = 0; f < fields.length; f++) {
3467 const field = fields[f].split('.');
3468 const value = (0,external_lodash_namespaceObject.get)(item, field);
3469 (0,external_lodash_namespaceObject.set)(filteredItem, field, value);
3470 }
3471
3472 return filteredItem;
3473 }
3474
3475 return item;
3476 }
3477 /**
3478 * Returns the Entity's record object by key. Doesn't trigger a resolver nor requests the entity from the API if the entity record isn't available in the local state.
3479 *
3480 * @param {Object} state State tree
3481 * @param {string} kind Entity kind.
3482 * @param {string} name Entity name.
3483 * @param {number} key Record's key
3484 *
3485 * @return {Object|null} Record.
3486 */
3487
3488 function __experimentalGetEntityRecordNoResolver(state, kind, name, key) {
3489 return getEntityRecord(state, kind, name, key);
3490 }
3491 /**
3492 * Returns the entity's record object by key,
3493 * with its attributes mapped to their raw values.
3494 *
3495 * @param {Object} state State tree.
3496 * @param {string} kind Entity kind.
3497 * @param {string} name Entity name.
3498 * @param {number} key Record's key.
3499 *
3500 * @return {Object?} Object with the entity's raw attributes.
3501 */
3502
3503 const getRawEntityRecord = rememo((state, kind, name, key) => {
3504 const record = getEntityRecord(state, kind, name, key);
3505 return record && Object.keys(record).reduce((accumulator, _key) => {
3506 if (isRawAttribute(getEntity(state, kind, name), _key)) {
3507 // Because edits are the "raw" attribute values,
3508 // we return those from record selectors to make rendering,
3509 // comparisons, and joins with edits easier.
3510 accumulator[_key] = (0,external_lodash_namespaceObject.get)(record[_key], 'raw', record[_key]);
3511 } else {
3512 accumulator[_key] = record[_key];
3513 }
3514
3515 return accumulator;
3516 }, {});
3517 }, state => [state.entities.data]);
3518 /**
3519 * Returns true if records have been received for the given set of parameters,
3520 * or false otherwise.
3521 *
3522 * @param {Object} state State tree
3523 * @param {string} kind Entity kind.
3524 * @param {string} name Entity name.
3525 * @param {?Object} query Optional terms query.
3526 *
3527 * @return {boolean} Whether entity records have been received.
3528 */
3529
3530 function hasEntityRecords(state, kind, name, query) {
3531 return Array.isArray(getEntityRecords(state, kind, name, query));
3532 }
3533 /**
3534 * Returns the Entity's records.
3535 *
3536 * @param {Object} state State tree
3537 * @param {string} kind Entity kind.
3538 * @param {string} name Entity name.
3539 * @param {?Object} query Optional terms query.
3540 *
3541 * @return {?Array} Records.
3542 */
3543
3544 function getEntityRecords(state, kind, name, query) {
3545 // Queried data state is prepopulated for all known entities. If this is not
3546 // assigned for the given parameters, then it is known to not exist. Thus, a
3547 // return value of an empty array is used instead of `null` (where `null` is
3548 // otherwise used to represent an unknown state).
3549 const queriedState = (0,external_lodash_namespaceObject.get)(state.entities.data, [kind, name, 'queriedData']);
3550
3551 if (!queriedState) {
3552 return EMPTY_ARRAY;
3553 }
3554
3555 return getQueriedItems(queriedState, query);
3556 }
3557 /**
3558 * Returns the list of dirty entity records.
3559 *
3560 * @param {Object} state State tree.
3561 *
3562 * @return {[{ title: string, key: string, name: string, kind: string }]} The list of updated records
3563 */
3564
3565 const __experimentalGetDirtyEntityRecords = rememo(state => {
3566 const {
3567 entities: {
3568 data
3569 }
3570 } = state;
3571 const dirtyRecords = [];
3572 Object.keys(data).forEach(kind => {
3573 Object.keys(data[kind]).forEach(name => {
3574 const primaryKeys = Object.keys(data[kind][name].edits).filter(primaryKey => hasEditsForEntityRecord(state, kind, name, primaryKey));
3575
3576 if (primaryKeys.length) {
3577 const entity = getEntity(state, kind, name);
3578 primaryKeys.forEach(primaryKey => {
3579 var _entity$getTitle;
3580
3581 const entityRecord = getEditedEntityRecord(state, kind, name, primaryKey);
3582 dirtyRecords.push({
3583 // We avoid using primaryKey because it's transformed into a string
3584 // when it's used as an object key.
3585 key: entityRecord[entity.key || DEFAULT_ENTITY_KEY],
3586 title: (entity === null || entity === void 0 ? void 0 : (_entity$getTitle = entity.getTitle) === null || _entity$getTitle === void 0 ? void 0 : _entity$getTitle.call(entity, entityRecord)) || '',
3587 name,
3588 kind
3589 });
3590 });
3591 }
3592 });
3593 });
3594 return dirtyRecords;
3595 }, state => [state.entities.data]);
3596 /**
3597 * Returns the list of entities currently being saved.
3598 *
3599 * @param {Object} state State tree.
3600 *
3601 * @return {[{ title: string, key: string, name: string, kind: string }]} The list of records being saved.
3602 */
3603
3604 const __experimentalGetEntitiesBeingSaved = rememo(state => {
3605 const {
3606 entities: {
3607 data
3608 }
3609 } = state;
3610 const recordsBeingSaved = [];
3611 Object.keys(data).forEach(kind => {
3612 Object.keys(data[kind]).forEach(name => {
3613 const primaryKeys = Object.keys(data[kind][name].saving).filter(primaryKey => isSavingEntityRecord(state, kind, name, primaryKey));
3614
3615 if (primaryKeys.length) {
3616 const entity = getEntity(state, kind, name);
3617 primaryKeys.forEach(primaryKey => {
3618 var _entity$getTitle2;
3619
3620 const entityRecord = getEditedEntityRecord(state, kind, name, primaryKey);
3621 recordsBeingSaved.push({
3622 // We avoid using primaryKey because it's transformed into a string
3623 // when it's used as an object key.
3624 key: entityRecord[entity.key || DEFAULT_ENTITY_KEY],
3625 title: (entity === null || entity === void 0 ? void 0 : (_entity$getTitle2 = entity.getTitle) === null || _entity$getTitle2 === void 0 ? void 0 : _entity$getTitle2.call(entity, entityRecord)) || '',
3626 name,
3627 kind
3628 });
3629 });
3630 }
3631 });
3632 });
3633 return recordsBeingSaved;
3634 }, state => [state.entities.data]);
3635 /**
3636 * Returns the specified entity record's edits.
3637 *
3638 * @param {Object} state State tree.
3639 * @param {string} kind Entity kind.
3640 * @param {string} name Entity name.
3641 * @param {number} recordId Record ID.
3642 *
3643 * @return {Object?} The entity record's edits.
3644 */
3645
3646 function getEntityRecordEdits(state, kind, name, recordId) {
3647 return (0,external_lodash_namespaceObject.get)(state.entities.data, [kind, name, 'edits', recordId]);
3648 }
3649 /**
3650 * Returns the specified entity record's non transient edits.
3651 *
3652 * Transient edits don't create an undo level, and
3653 * are not considered for change detection.
3654 * They are defined in the entity's config.
3655 *
3656 * @param {Object} state State tree.
3657 * @param {string} kind Entity kind.
3658 * @param {string} name Entity name.
3659 * @param {number} recordId Record ID.
3660 *
3661 * @return {Object?} The entity record's non transient edits.
3662 */
3663
3664 const getEntityRecordNonTransientEdits = rememo((state, kind, name, recordId) => {
3665 const {
3666 transientEdits
3667 } = getEntity(state, kind, name) || {};
3668 const edits = getEntityRecordEdits(state, kind, name, recordId) || {};
3669
3670 if (!transientEdits) {
3671 return edits;
3672 }
3673
3674 return Object.keys(edits).reduce((acc, key) => {
3675 if (!transientEdits[key]) {
3676 acc[key] = edits[key];
3677 }
3678
3679 return acc;
3680 }, {});
3681 }, state => [state.entities.config, state.entities.data]);
3682 /**
3683 * Returns true if the specified entity record has edits,
3684 * and false otherwise.
3685 *
3686 * @param {Object} state State tree.
3687 * @param {string} kind Entity kind.
3688 * @param {string} name Entity name.
3689 * @param {number} recordId Record ID.
3690 *
3691 * @return {boolean} Whether the entity record has edits or not.
3692 */
3693
3694 function hasEditsForEntityRecord(state, kind, name, recordId) {
3695 return isSavingEntityRecord(state, kind, name, recordId) || Object.keys(getEntityRecordNonTransientEdits(state, kind, name, recordId)).length > 0;
3696 }
3697 /**
3698 * Returns the specified entity record, merged with its edits.
3699 *
3700 * @param {Object} state State tree.
3701 * @param {string} kind Entity kind.
3702 * @param {string} name Entity name.
3703 * @param {number} recordId Record ID.
3704 *
3705 * @return {Object?} The entity record, merged with its edits.
3706 */
3707
3708 const getEditedEntityRecord = rememo((state, kind, name, recordId) => ({ ...getRawEntityRecord(state, kind, name, recordId),
3709 ...getEntityRecordEdits(state, kind, name, recordId)
3710 }), state => [state.entities.data]);
3711 /**
3712 * Returns true if the specified entity record is autosaving, and false otherwise.
3713 *
3714 * @param {Object} state State tree.
3715 * @param {string} kind Entity kind.
3716 * @param {string} name Entity name.
3717 * @param {number} recordId Record ID.
3718 *
3719 * @return {boolean} Whether the entity record is autosaving or not.
3720 */
3721
3722 function isAutosavingEntityRecord(state, kind, name, recordId) {
3723 const {
3724 pending,
3725 isAutosave
3726 } = (0,external_lodash_namespaceObject.get)(state.entities.data, [kind, name, 'saving', recordId], {});
3727 return Boolean(pending && isAutosave);
3728 }
3729 /**
3730 * Returns true if the specified entity record is saving, and false otherwise.
3731 *
3732 * @param {Object} state State tree.
3733 * @param {string} kind Entity kind.
3734 * @param {string} name Entity name.
3735 * @param {number} recordId Record ID.
3736 *
3737 * @return {boolean} Whether the entity record is saving or not.
3738 */
3739
3740 function isSavingEntityRecord(state, kind, name, recordId) {
3741 return (0,external_lodash_namespaceObject.get)(state.entities.data, [kind, name, 'saving', recordId, 'pending'], false);
3742 }
3743 /**
3744 * Returns true if the specified entity record is deleting, and false otherwise.
3745 *
3746 * @param {Object} state State tree.
3747 * @param {string} kind Entity kind.
3748 * @param {string} name Entity name.
3749 * @param {number} recordId Record ID.
3750 *
3751 * @return {boolean} Whether the entity record is deleting or not.
3752 */
3753
3754 function isDeletingEntityRecord(state, kind, name, recordId) {
3755 return (0,external_lodash_namespaceObject.get)(state.entities.data, [kind, name, 'deleting', recordId, 'pending'], false);
3756 }
3757 /**
3758 * Returns the specified entity record's last save error.
3759 *
3760 * @param {Object} state State tree.
3761 * @param {string} kind Entity kind.
3762 * @param {string} name Entity name.
3763 * @param {number} recordId Record ID.
3764 *
3765 * @return {Object?} The entity record's save error.
3766 */
3767
3768 function getLastEntitySaveError(state, kind, name, recordId) {
3769 return (0,external_lodash_namespaceObject.get)(state.entities.data, [kind, name, 'saving', recordId, 'error']);
3770 }
3771 /**
3772 * Returns the specified entity record's last delete error.
3773 *
3774 * @param {Object} state State tree.
3775 * @param {string} kind Entity kind.
3776 * @param {string} name Entity name.
3777 * @param {number} recordId Record ID.
3778 *
3779 * @return {Object?} The entity record's save error.
3780 */
3781
3782 function getLastEntityDeleteError(state, kind, name, recordId) {
3783 return (0,external_lodash_namespaceObject.get)(state.entities.data, [kind, name, 'deleting', recordId, 'error']);
3784 }
3785 /**
3786 * Returns the current undo offset for the
3787 * entity records edits history. The offset
3788 * represents how many items from the end
3789 * of the history stack we are at. 0 is the
3790 * last edit, -1 is the second last, and so on.
3791 *
3792 * @param {Object} state State tree.
3793 *
3794 * @return {number} The current undo offset.
3795 */
3796
3797 function getCurrentUndoOffset(state) {
3798 return state.undo.offset;
3799 }
3800 /**
3801 * Returns the previous edit from the current undo offset
3802 * for the entity records edits history, if any.
3803 *
3804 * @param {Object} state State tree.
3805 *
3806 * @return {Object?} The edit.
3807 */
3808
3809
3810 function getUndoEdit(state) {
3811 return state.undo[state.undo.length - 2 + getCurrentUndoOffset(state)];
3812 }
3813 /**
3814 * Returns the next edit from the current undo offset
3815 * for the entity records edits history, if any.
3816 *
3817 * @param {Object} state State tree.
3818 *
3819 * @return {Object?} The edit.
3820 */
3821
3822 function getRedoEdit(state) {
3823 return state.undo[state.undo.length + getCurrentUndoOffset(state)];
3824 }
3825 /**
3826 * Returns true if there is a previous edit from the current undo offset
3827 * for the entity records edits history, and false otherwise.
3828 *
3829 * @param {Object} state State tree.
3830 *
3831 * @return {boolean} Whether there is a previous edit or not.
3832 */
3833
3834 function hasUndo(state) {
3835 return Boolean(getUndoEdit(state));
3836 }
3837 /**
3838 * Returns true if there is a next edit from the current undo offset
3839 * for the entity records edits history, and false otherwise.
3840 *
3841 * @param {Object} state State tree.
3842 *
3843 * @return {boolean} Whether there is a next edit or not.
3844 */
3845
3846 function hasRedo(state) {
3847 return Boolean(getRedoEdit(state));
3848 }
3849 /**
3850 * Return the current theme.
3851 *
3852 * @param {Object} state Data state.
3853 *
3854 * @return {Object} The current theme.
3855 */
3856
3857 function getCurrentTheme(state) {
3858 return state.themes[state.currentTheme];
3859 }
3860 /**
3861 * Return theme supports data in the index.
3862 *
3863 * @param {Object} state Data state.
3864 *
3865 * @return {*} Index data.
3866 */
3867
3868 function getThemeSupports(state) {
3869 return state.themeSupports;
3870 }
3871 /**
3872 * Returns the embed preview for the given URL.
3873 *
3874 * @param {Object} state Data state.
3875 * @param {string} url Embedded URL.
3876 *
3877 * @return {*} Undefined if the preview has not been fetched, otherwise, the preview fetched from the embed preview API.
3878 */
3879
3880 function getEmbedPreview(state, url) {
3881 return state.embedPreviews[url];
3882 }
3883 /**
3884 * Determines if the returned preview is an oEmbed link fallback.
3885 *
3886 * WordPress can be configured to return a simple link to a URL if it is not embeddable.
3887 * We need to be able to determine if a URL is embeddable or not, based on what we
3888 * get back from the oEmbed preview API.
3889 *
3890 * @param {Object} state Data state.
3891 * @param {string} url Embedded URL.
3892 *
3893 * @return {boolean} Is the preview for the URL an oEmbed link fallback.
3894 */
3895
3896 function isPreviewEmbedFallback(state, url) {
3897 const preview = state.embedPreviews[url];
3898 const oEmbedLinkCheck = '<a href="' + url + '">' + url + '</a>';
3899
3900 if (!preview) {
3901 return false;
3902 }
3903
3904 return preview.html === oEmbedLinkCheck;
3905 }
3906 /**
3907 * Returns whether the current user can perform the given action on the given
3908 * REST resource.
3909 *
3910 * Calling this may trigger an OPTIONS request to the REST API via the
3911 * `canUser()` resolver.
3912 *
3913 * https://developer.wordpress.org/rest-api/reference/
3914 *
3915 * @param {Object} state Data state.
3916 * @param {string} action Action to check. One of: 'create', 'read', 'update', 'delete'.
3917 * @param {string} resource REST resource to check, e.g. 'media' or 'posts'.
3918 * @param {string=} id Optional ID of the rest resource to check.
3919 *
3920 * @return {boolean|undefined} Whether or not the user can perform the action,
3921 * or `undefined` if the OPTIONS request is still being made.
3922 */
3923
3924 function canUser(state, action, resource, id) {
3925 const key = (0,external_lodash_namespaceObject.compact)([action, resource, id]).join('/');
3926 return (0,external_lodash_namespaceObject.get)(state, ['userPermissions', key]);
3927 }
3928 /**
3929 * Returns whether the current user can edit the given entity.
3930 *
3931 * Calling this may trigger an OPTIONS request to the REST API via the
3932 * `canUser()` resolver.
3933 *
3934 * https://developer.wordpress.org/rest-api/reference/
3935 *
3936 * @param {Object} state Data state.
3937 * @param {string} kind Entity kind.
3938 * @param {string} name Entity name.
3939 * @param {string} recordId Record's id.
3940 * @return {boolean|undefined} Whether or not the user can edit,
3941 * or `undefined` if the OPTIONS request is still being made.
3942 */
3943
3944 function canUserEditEntityRecord(state, kind, name, recordId) {
3945 const entity = getEntity(state, kind, name);
3946
3947 if (!entity) {
3948 return false;
3949 }
3950
3951 const resource = entity.__unstable_rest_base;
3952 return canUser(state, 'update', resource, recordId);
3953 }
3954 /**
3955 * Returns the latest autosaves for the post.
3956 *
3957 * May return multiple autosaves since the backend stores one autosave per
3958 * author for each post.
3959 *
3960 * @param {Object} state State tree.
3961 * @param {string} postType The type of the parent post.
3962 * @param {number} postId The id of the parent post.
3963 *
3964 * @return {?Array} An array of autosaves for the post, or undefined if there is none.
3965 */
3966
3967 function getAutosaves(state, postType, postId) {
3968 return state.autosaves[postId];
3969 }
3970 /**
3971 * Returns the autosave for the post and author.
3972 *
3973 * @param {Object} state State tree.
3974 * @param {string} postType The type of the parent post.
3975 * @param {number} postId The id of the parent post.
3976 * @param {number} authorId The id of the author.
3977 *
3978 * @return {?Object} The autosave for the post and author.
3979 */
3980
3981 function getAutosave(state, postType, postId, authorId) {
3982 if (authorId === undefined) {
3983 return;
3984 }
3985
3986 const autosaves = state.autosaves[postId];
3987 return (0,external_lodash_namespaceObject.find)(autosaves, {
3988 author: authorId
3989 });
3990 }
3991 /**
3992 * Returns true if the REST request for autosaves has completed.
3993 *
3994 * @param {Object} state State tree.
3995 * @param {string} postType The type of the parent post.
3996 * @param {number} postId The id of the parent post.
3997 *
3998 * @return {boolean} True if the REST request was completed. False otherwise.
3999 */
4000
4001 const hasFetchedAutosaves = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (state, postType, postId) => {
4002 return select(STORE_NAME).hasFinishedResolution('getAutosaves', [postType, postId]);
4003 });
4004 /**
4005 * Returns a new reference when edited values have changed. This is useful in
4006 * inferring where an edit has been made between states by comparison of the
4007 * return values using strict equality.
4008 *
4009 * @example
4010 *
4011 * ```
4012 * const hasEditOccurred = (
4013 * getReferenceByDistinctEdits( beforeState ) !==
4014 * getReferenceByDistinctEdits( afterState )
4015 * );
4016 * ```
4017 *
4018 * @param {Object} state Editor state.
4019 *
4020 * @return {*} A value whose reference will change only when an edit occurs.
4021 */
4022
4023 const getReferenceByDistinctEdits = rememo(() => [], state => [state.undo.length, state.undo.offset, state.undo.flattenedUndo]);
4024 /**
4025 * Retrieve the frontend template used for a given link.
4026 *
4027 * @param {Object} state Editor state.
4028 * @param {string} link Link.
4029 *
4030 * @return {Object?} The template record.
4031 */
4032
4033 function __experimentalGetTemplateForLink(state, link) {
4034 const records = getEntityRecords(state, 'postType', 'wp_template', {
4035 'find-template': link
4036 });
4037 const template = records !== null && records !== void 0 && records.length ? records[0] : null;
4038
4039 if (template) {
4040 return getEditedEntityRecord(state, 'postType', 'wp_template', template.id);
4041 }
4042
4043 return template;
4044 }
4045 //# sourceMappingURL=selectors.js.map
4046 ;// CONCATENATED MODULE: ./packages/core-data/build-module/utils/if-not-resolved.js
4047 /**
4048 * Higher-order function which invokes the given resolver only if it has not
4049 * already been resolved with the arguments passed to the enhanced function.
4050 *
4051 * This only considers resolution state, and notably does not support resolver
4052 * custom `isFulfilled` behavior.
4053 *
4054 * @param {Function} resolver Original resolver.
4055 * @param {string} selectorName Selector name associated with resolver.
4056 *
4057 * @return {Function} Enhanced resolver.
4058 */
4059 const ifNotResolved = (resolver, selectorName) => (...args) => async ({
4060 select,
4061 dispatch
4062 }) => {
4063 if (!select.hasStartedResolution(selectorName, args)) {
4064 await dispatch(resolver(...args));
4065 }
4066 };
4067
4068 /* harmony default export */ var if_not_resolved = (ifNotResolved);
4069 //# sourceMappingURL=if-not-resolved.js.map
4070 ;// CONCATENATED MODULE: ./packages/core-data/build-module/resolvers.js
4071 /**
4072 * External dependencies
4073 */
4074
4075 /**
4076 * WordPress dependencies
4077 */
4078
4079
4080
4081 /**
4082 * Internal dependencies
4083 */
4084
4085
4086
4087
4088 /**
4089 * Requests authors from the REST API.
4090 *
4091 * @param {Object|undefined} query Optional object of query parameters to
4092 * include with request.
4093 */
4094
4095 const resolvers_getAuthors = query => async ({
4096 dispatch
4097 }) => {
4098 const path = (0,external_wp_url_namespaceObject.addQueryArgs)('/wp/v2/users/?who=authors&per_page=100', query);
4099 const users = await external_wp_apiFetch_default()({
4100 path
4101 });
4102 dispatch.receiveUserQuery(path, users);
4103 };
4104 /**
4105 * Requests the current user from the REST API.
4106 */
4107
4108 const resolvers_getCurrentUser = () => async ({
4109 dispatch
4110 }) => {
4111 const currentUser = await external_wp_apiFetch_default()({
4112 path: '/wp/v2/users/me'
4113 });
4114 dispatch.receiveCurrentUser(currentUser);
4115 };
4116 /**
4117 * Requests an entity's record from the REST API.
4118 *
4119 * @param {string} kind Entity kind.
4120 * @param {string} name Entity name.
4121 * @param {number|string} key Record's key
4122 * @param {Object|undefined} query Optional object of query parameters to
4123 * include with request.
4124 */
4125
4126 const resolvers_getEntityRecord = (kind, name, key = '', query) => async ({
4127 select,
4128 dispatch
4129 }) => {
4130 const entities = await dispatch(getKindEntities(kind));
4131 const entity = (0,external_lodash_namespaceObject.find)(entities, {
4132 kind,
4133 name
4134 });
4135
4136 if (!entity || entity !== null && entity !== void 0 && entity.__experimentalNoFetch) {
4137 return;
4138 }
4139
4140 const lock = await dispatch.__unstableAcquireStoreLock(STORE_NAME, ['entities', 'data', kind, name, key], {
4141 exclusive: false
4142 });
4143
4144 try {
4145 if (query !== undefined && query._fields) {
4146 // If requesting specific fields, items and query association to said
4147 // records are stored by ID reference. Thus, fields must always include
4148 // the ID.
4149 query = { ...query,
4150 _fields: (0,external_lodash_namespaceObject.uniq)([...(get_normalized_comma_separable(query._fields) || []), entity.key || DEFAULT_ENTITY_KEY]).join()
4151 };
4152 } // Disable reason: While true that an early return could leave `path`
4153 // unused, it's important that path is derived using the query prior to
4154 // additional query modifications in the condition below, since those
4155 // modifications are relevant to how the data is tracked in state, and not
4156 // for how the request is made to the REST API.
4157 // eslint-disable-next-line @wordpress/no-unused-vars-before-return
4158
4159
4160 const path = (0,external_wp_url_namespaceObject.addQueryArgs)(entity.baseURL + '/' + key, { ...entity.baseURLParams,
4161 ...query
4162 });
4163
4164 if (query !== undefined) {
4165 query = { ...query,
4166 include: [key]
4167 }; // The resolution cache won't consider query as reusable based on the
4168 // fields, so it's tested here, prior to initiating the REST request,
4169 // and without causing `getEntityRecords` resolution to occur.
4170
4171 const hasRecords = select.hasEntityRecords(kind, name, query);
4172
4173 if (hasRecords) {
4174 return;
4175 }
4176 }
4177
4178 const record = await external_wp_apiFetch_default()({
4179 path
4180 });
4181 dispatch.receiveEntityRecords(kind, name, record, query);
4182 } catch (error) {// We need a way to handle and access REST API errors in state
4183 // Until then, catching the error ensures the resolver is marked as resolved.
4184 } finally {
4185 dispatch.__unstableReleaseStoreLock(lock);
4186 }
4187 };
4188 /**
4189 * Requests an entity's record from the REST API.
4190 */
4191
4192 const resolvers_getRawEntityRecord = if_not_resolved(resolvers_getEntityRecord, 'getEntityRecord');
4193 /**
4194 * Requests an entity's record from the REST API.
4195 */
4196
4197 const resolvers_getEditedEntityRecord = if_not_resolved(resolvers_getRawEntityRecord, 'getRawEntityRecord');
4198 /**
4199 * Requests the entity's records from the REST API.
4200 *
4201 * @param {string} kind Entity kind.
4202 * @param {string} name Entity name.
4203 * @param {Object?} query Query Object.
4204 */
4205
4206 const resolvers_getEntityRecords = (kind, name, query = {}) => async ({
4207 dispatch
4208 }) => {
4209 const entities = await dispatch(getKindEntities(kind));
4210 const entity = (0,external_lodash_namespaceObject.find)(entities, {
4211 kind,
4212 name
4213 });
4214
4215 if (!entity || entity !== null && entity !== void 0 && entity.__experimentalNoFetch) {
4216 return;
4217 }
4218
4219 const lock = await dispatch.__unstableAcquireStoreLock(STORE_NAME, ['entities', 'data', kind, name], {
4220 exclusive: false
4221 });
4222
4223 try {
4224 var _query;
4225
4226 if (query._fields) {
4227 // If requesting specific fields, items and query association to said
4228 // records are stored by ID reference. Thus, fields must always include
4229 // the ID.
4230 query = { ...query,
4231 _fields: (0,external_lodash_namespaceObject.uniq)([...(get_normalized_comma_separable(query._fields) || []), entity.key || DEFAULT_ENTITY_KEY]).join()
4232 };
4233 }
4234
4235 const path = (0,external_wp_url_namespaceObject.addQueryArgs)(entity.baseURL, { ...entity.baseURLParams,
4236 ...query
4237 });
4238 let records = Object.values(await external_wp_apiFetch_default()({
4239 path
4240 })); // If we request fields but the result doesn't contain the fields,
4241 // explicitely set these fields as "undefined"
4242 // that way we consider the query "fullfilled".
4243
4244 if (query._fields) {
4245 records = records.map(record => {
4246 query._fields.split(',').forEach(field => {
4247 if (!record.hasOwnProperty(field)) {
4248 record[field] = undefined;
4249 }
4250 });
4251
4252 return record;
4253 });
4254 }
4255
4256 dispatch.receiveEntityRecords(kind, name, records, query); // When requesting all fields, the list of results can be used to
4257 // resolve the `getEntityRecord` selector in addition to `getEntityRecords`.
4258 // See https://github.com/WordPress/gutenberg/pull/26575
4259
4260 if (!((_query = query) !== null && _query !== void 0 && _query._fields) && !query.context) {
4261 const key = entity.key || DEFAULT_ENTITY_KEY;
4262 const resolutionsArgs = records.filter(record => record[key]).map(record => [kind, name, record[key]]);
4263 dispatch({
4264 type: 'START_RESOLUTIONS',
4265 selectorName: 'getEntityRecord',
4266 args: resolutionsArgs
4267 });
4268 dispatch({
4269 type: 'FINISH_RESOLUTIONS',
4270 selectorName: 'getEntityRecord',
4271 args: resolutionsArgs
4272 });
4273 }
4274 } finally {
4275 dispatch.__unstableReleaseStoreLock(lock);
4276 }
4277 };
4278
4279 resolvers_getEntityRecords.shouldInvalidate = (action, kind, name) => {
4280 return (action.type === 'RECEIVE_ITEMS' || action.type === 'REMOVE_ITEMS') && action.invalidateCache && kind === action.kind && name === action.name;
4281 };
4282 /**
4283 * Requests the current theme.
4284 */
4285
4286
4287 const resolvers_getCurrentTheme = () => async ({
4288 dispatch
4289 }) => {
4290 const activeThemes = await external_wp_apiFetch_default()({
4291 path: '/wp/v2/themes?status=active'
4292 });
4293 dispatch.receiveCurrentTheme(activeThemes[0]);
4294 };
4295 /**
4296 * Requests theme supports data from the index.
4297 */
4298
4299 const resolvers_getThemeSupports = () => async ({
4300 dispatch
4301 }) => {
4302 const activeThemes = await external_wp_apiFetch_default()({
4303 path: '/wp/v2/themes?status=active'
4304 });
4305 dispatch.receiveThemeSupports(activeThemes[0].theme_supports);
4306 };
4307 /**
4308 * Requests a preview from the from the Embed API.
4309 *
4310 * @param {string} url URL to get the preview for.
4311 */
4312
4313 const resolvers_getEmbedPreview = url => async ({
4314 dispatch
4315 }) => {
4316 try {
4317 const embedProxyResponse = await external_wp_apiFetch_default()({
4318 path: (0,external_wp_url_namespaceObject.addQueryArgs)('/oembed/1.0/proxy', {
4319 url
4320 })
4321 });
4322 dispatch.receiveEmbedPreview(url, embedProxyResponse);
4323 } catch (error) {
4324 // Embed API 404s if the URL cannot be embedded, so we have to catch the error from the apiRequest here.
4325 dispatch.receiveEmbedPreview(url, false);
4326 }
4327 };
4328 /**
4329 * Checks whether the current user can perform the given action on the given
4330 * REST resource.
4331 *
4332 * @param {string} action Action to check. One of: 'create', 'read', 'update',
4333 * 'delete'.
4334 * @param {string} resource REST resource to check, e.g. 'media' or 'posts'.
4335 * @param {?string} id ID of the rest resource to check.
4336 */
4337
4338 const resolvers_canUser = (action, resource, id) => async ({
4339 dispatch
4340 }) => {
4341 const methods = {
4342 create: 'POST',
4343 read: 'GET',
4344 update: 'PUT',
4345 delete: 'DELETE'
4346 };
4347 const method = methods[action];
4348
4349 if (!method) {
4350 throw new Error(`'${action}' is not a valid action.`);
4351 }
4352
4353 const path = id ? `/wp/v2/${resource}/${id}` : `/wp/v2/${resource}`;
4354 let response;
4355
4356 try {
4357 response = await external_wp_apiFetch_default()({
4358 path,
4359 // Ideally this would always be an OPTIONS request, but unfortunately there's
4360 // a bug in the REST API which causes the Allow header to not be sent on
4361 // OPTIONS requests to /posts/:id routes.
4362 // https://core.trac.wordpress.org/ticket/45753
4363 method: id ? 'GET' : 'OPTIONS',
4364 parse: false
4365 });
4366 } catch (error) {
4367 // Do nothing if our OPTIONS request comes back with an API error (4xx or
4368 // 5xx). The previously determined isAllowed value will remain in the store.
4369 return;
4370 }
4371
4372 let allowHeader;
4373
4374 if ((0,external_lodash_namespaceObject.hasIn)(response, ['headers', 'get'])) {
4375 // If the request is fetched using the fetch api, the header can be
4376 // retrieved using the 'get' method.
4377 allowHeader = response.headers.get('allow');
4378 } else {
4379 // If the request was preloaded server-side and is returned by the
4380 // preloading middleware, the header will be a simple property.
4381 allowHeader = (0,external_lodash_namespaceObject.get)(response, ['headers', 'Allow'], '');
4382 }
4383
4384 const key = (0,external_lodash_namespaceObject.compact)([action, resource, id]).join('/');
4385 const isAllowed = (0,external_lodash_namespaceObject.includes)(allowHeader, method);
4386 dispatch.receiveUserPermission(key, isAllowed);
4387 };
4388 /**
4389 * Checks whether the current user can perform the given action on the given
4390 * REST resource.
4391 *
4392 * @param {string} kind Entity kind.
4393 * @param {string} name Entity name.
4394 * @param {string} recordId Record's id.
4395 */
4396
4397 const resolvers_canUserEditEntityRecord = (kind, name, recordId) => async ({
4398 dispatch
4399 }) => {
4400 const entities = await dispatch(getKindEntities(kind));
4401 const entity = (0,external_lodash_namespaceObject.find)(entities, {
4402 kind,
4403 name
4404 });
4405
4406 if (!entity) {
4407 return;
4408 }
4409
4410 const resource = entity.__unstable_rest_base;
4411 await dispatch(resolvers_canUser('update', resource, recordId));
4412 };
4413 /**
4414 * Request autosave data from the REST API.
4415 *
4416 * @param {string} postType The type of the parent post.
4417 * @param {number} postId The id of the parent post.
4418 */
4419
4420 const resolvers_getAutosaves = (postType, postId) => async ({
4421 dispatch,
4422 resolveSelect
4423 }) => {
4424 const {
4425 rest_base: restBase
4426 } = await resolveSelect.getPostType(postType);
4427 const autosaves = await external_wp_apiFetch_default()({
4428 path: `/wp/v2/${restBase}/${postId}/autosaves?context=edit`
4429 });
4430
4431 if (autosaves && autosaves.length) {
4432 dispatch.receiveAutosaves(postId, autosaves);
4433 }
4434 };
4435 /**
4436 * Request autosave data from the REST API.
4437 *
4438 * This resolver exists to ensure the underlying autosaves are fetched via
4439 * `getAutosaves` when a call to the `getAutosave` selector is made.
4440 *
4441 * @param {string} postType The type of the parent post.
4442 * @param {number} postId The id of the parent post.
4443 */
4444
4445 const resolvers_getAutosave = (postType, postId) => async ({
4446 resolveSelect
4447 }) => {
4448 await resolveSelect.getAutosaves(postType, postId);
4449 };
4450 /**
4451 * Retrieve the frontend template used for a given link.
4452 *
4453 * @param {string} link Link.
4454 */
4455
4456 const resolvers_experimentalGetTemplateForLink = link => async ({
4457 dispatch,
4458 resolveSelect
4459 }) => {
4460 // Ideally this should be using an apiFetch call
4461 // We could potentially do so by adding a "filter" to the `wp_template` end point.
4462 // Also it seems the returned object is not a regular REST API post type.
4463 let template;
4464
4465 try {
4466 template = await window.fetch((0,external_wp_url_namespaceObject.addQueryArgs)(link, {
4467 '_wp-find-template': true
4468 })).then(res => res.json()).then(({
4469 data
4470 }) => data);
4471 } catch (e) {// For non-FSE themes, it is possible that this request returns an error.
4472 }
4473
4474 if (!template) {
4475 return;
4476 }
4477
4478 const record = await resolveSelect.getEntityRecord('postType', 'wp_template', template.id);
4479
4480 if (record) {
4481 dispatch.receiveEntityRecords('postType', 'wp_template', [record], {
4482 'find-template': link
4483 });
4484 }
4485 };
4486
4487 resolvers_experimentalGetTemplateForLink.shouldInvalidate = action => {
4488 return (action.type === 'RECEIVE_ITEMS' || action.type === 'REMOVE_ITEMS') && action.invalidateCache && action.kind === 'postType' && action.name === 'wp_template';
4489 };
4490 //# sourceMappingURL=resolvers.js.map
4491 ;// CONCATENATED MODULE: ./packages/core-data/build-module/locks/utils.js
4492 function deepCopyLocksTreePath(tree, path) {
4493 const newTree = { ...tree
4494 };
4495 let currentNode = newTree;
4496
4497 for (const branchName of path) {
4498 currentNode.children = { ...currentNode.children,
4499 [branchName]: {
4500 locks: [],
4501 children: {},
4502 ...currentNode.children[branchName]
4503 }
4504 };
4505 currentNode = currentNode.children[branchName];
4506 }
4507
4508 return newTree;
4509 }
4510 function getNode(tree, path) {
4511 let currentNode = tree;
4512
4513 for (const branchName of path) {
4514 const nextNode = currentNode.children[branchName];
4515
4516 if (!nextNode) {
4517 return null;
4518 }
4519
4520 currentNode = nextNode;
4521 }
4522
4523 return currentNode;
4524 }
4525 function* iteratePath(tree, path) {
4526 let currentNode = tree;
4527 yield currentNode;
4528
4529 for (const branchName of path) {
4530 const nextNode = currentNode.children[branchName];
4531
4532 if (!nextNode) {
4533 break;
4534 }
4535
4536 yield nextNode;
4537 currentNode = nextNode;
4538 }
4539 }
4540 function* iterateDescendants(node) {
4541 const stack = Object.values(node.children);
4542
4543 while (stack.length) {
4544 const childNode = stack.pop();
4545 yield childNode;
4546 stack.push(...Object.values(childNode.children));
4547 }
4548 }
4549 function hasConflictingLock({
4550 exclusive
4551 }, locks) {
4552 if (exclusive && locks.length) {
4553 return true;
4554 }
4555
4556 if (!exclusive && locks.filter(lock => lock.exclusive).length) {
4557 return true;
4558 }
4559
4560 return false;
4561 }
4562 //# sourceMappingURL=utils.js.map
4563 ;// CONCATENATED MODULE: ./packages/core-data/build-module/locks/reducer.js
4564 /**
4565 * Internal dependencies
4566 */
4567
4568 const DEFAULT_STATE = {
4569 requests: [],
4570 tree: {
4571 locks: [],
4572 children: {}
4573 }
4574 };
4575 /**
4576 * Reducer returning locks.
4577 *
4578 * @param {Object} state Current state.
4579 * @param {Object} action Dispatched action.
4580 *
4581 * @return {Object} Updated state.
4582 */
4583
4584 function locks(state = DEFAULT_STATE, action) {
4585 switch (action.type) {
4586 case 'ENQUEUE_LOCK_REQUEST':
4587 {
4588 const {
4589 request
4590 } = action;
4591 return { ...state,
4592 requests: [request, ...state.requests]
4593 };
4594 }
4595
4596 case 'GRANT_LOCK_REQUEST':
4597 {
4598 const {
4599 lock,
4600 request
4601 } = action;
4602 const {
4603 store,
4604 path
4605 } = request;
4606 const storePath = [store, ...path];
4607 const newTree = deepCopyLocksTreePath(state.tree, storePath);
4608 const node = getNode(newTree, storePath);
4609 node.locks = [...node.locks, lock];
4610 return { ...state,
4611 requests: state.requests.filter(r => r !== request),
4612 tree: newTree
4613 };
4614 }
4615
4616 case 'RELEASE_LOCK':
4617 {
4618 const {
4619 lock
4620 } = action;
4621 const storePath = [lock.store, ...lock.path];
4622 const newTree = deepCopyLocksTreePath(state.tree, storePath);
4623 const node = getNode(newTree, storePath);
4624 node.locks = node.locks.filter(l => l !== lock);
4625 return { ...state,
4626 tree: newTree
4627 };
4628 }
4629 }
4630
4631 return state;
4632 }
4633 //# sourceMappingURL=reducer.js.map
4634 ;// CONCATENATED MODULE: ./packages/core-data/build-module/locks/selectors.js
4635 /**
4636 * Internal dependencies
4637 */
4638
4639 function getPendingLockRequests(state) {
4640 return state.requests;
4641 }
4642 function isLockAvailable(state, store, path, {
4643 exclusive
4644 }) {
4645 const storePath = [store, ...path];
4646 const locks = state.tree; // Validate all parents and the node itself
4647
4648 for (const node of iteratePath(locks, storePath)) {
4649 if (hasConflictingLock({
4650 exclusive
4651 }, node.locks)) {
4652 return false;
4653 }
4654 } // iteratePath terminates early if path is unreachable, let's
4655 // re-fetch the node and check it exists in the tree.
4656
4657
4658 const node = getNode(locks, storePath);
4659
4660 if (!node) {
4661 return true;
4662 } // Validate all nested nodes
4663
4664
4665 for (const descendant of iterateDescendants(node)) {
4666 if (hasConflictingLock({
4667 exclusive
4668 }, descendant.locks)) {
4669 return false;
4670 }
4671 }
4672
4673 return true;
4674 }
4675 //# sourceMappingURL=selectors.js.map
4676 ;// CONCATENATED MODULE: ./packages/core-data/build-module/locks/engine.js
4677 /**
4678 * Internal dependencies
4679 */
4680
4681
4682 function createLocks() {
4683 let state = locks(undefined, {
4684 type: '@@INIT'
4685 });
4686
4687 function processPendingLockRequests() {
4688 for (const request of getPendingLockRequests(state)) {
4689 const {
4690 store,
4691 path,
4692 exclusive,
4693 notifyAcquired
4694 } = request;
4695
4696 if (isLockAvailable(state, store, path, {
4697 exclusive
4698 })) {
4699 const lock = {
4700 store,
4701 path,
4702 exclusive
4703 };
4704 state = locks(state, {
4705 type: 'GRANT_LOCK_REQUEST',
4706 lock,
4707 request
4708 });
4709 notifyAcquired(lock);
4710 }
4711 }
4712 }
4713
4714 function acquire(store, path, exclusive) {
4715 return new Promise(resolve => {
4716 state = locks(state, {
4717 type: 'ENQUEUE_LOCK_REQUEST',
4718 request: {
4719 store,
4720 path,
4721 exclusive,
4722 notifyAcquired: resolve
4723 }
4724 });
4725 processPendingLockRequests();
4726 });
4727 }
4728
4729 function release(lock) {
4730 state = locks(state, {
4731 type: 'RELEASE_LOCK',
4732 lock
4733 });
4734 processPendingLockRequests();
4735 }
4736
4737 return {
4738 acquire,
4739 release
4740 };
4741 }
4742 //# sourceMappingURL=engine.js.map
4743 ;// CONCATENATED MODULE: ./packages/core-data/build-module/locks/actions.js
4744 /**
4745 * Internal dependencies
4746 */
4747
4748 function createLocksActions() {
4749 const locks = createLocks();
4750
4751 function __unstableAcquireStoreLock(store, path, {
4752 exclusive
4753 }) {
4754 return () => locks.acquire(store, path, exclusive);
4755 }
4756
4757 function __unstableReleaseStoreLock(lock) {
4758 return () => locks.release(lock);
4759 }
4760
4761 return {
4762 __unstableAcquireStoreLock,
4763 __unstableReleaseStoreLock
4764 };
4765 }
4766 //# sourceMappingURL=actions.js.map
4767 ;// CONCATENATED MODULE: external ["wp","element"]
4768 var external_wp_element_namespaceObject = window["wp"]["element"];
4769 ;// CONCATENATED MODULE: external ["wp","blocks"]
4770 var external_wp_blocks_namespaceObject = window["wp"]["blocks"];
4771 ;// CONCATENATED MODULE: ./packages/core-data/build-module/entity-provider.js
4772
4773
4774 /**
4775 * WordPress dependencies
4776 */
4777
4778
4779
4780 /**
4781 * Internal dependencies
4782 */
4783
4784
4785 const entity_provider_EMPTY_ARRAY = [];
4786 /**
4787 * Internal dependencies
4788 */
4789
4790
4791 const entity_provider_entities = { ...defaultEntities.reduce((acc, entity) => {
4792 if (!acc[entity.kind]) {
4793 acc[entity.kind] = {};
4794 }
4795
4796 acc[entity.kind][entity.name] = {
4797 context: (0,external_wp_element_namespaceObject.createContext)()
4798 };
4799 return acc;
4800 }, {}),
4801 ...kinds.reduce((acc, kind) => {
4802 acc[kind.name] = {};
4803 return acc;
4804 }, {})
4805 };
4806
4807 const entity_provider_getEntity = (kind, type) => {
4808 if (!entity_provider_entities[kind]) {
4809 throw new Error(`Missing entity config for kind: ${kind}.`);
4810 }
4811
4812 if (!entity_provider_entities[kind][type]) {
4813 entity_provider_entities[kind][type] = {
4814 context: (0,external_wp_element_namespaceObject.createContext)()
4815 };
4816 }
4817
4818 return entity_provider_entities[kind][type];
4819 };
4820 /**
4821 * Context provider component for providing
4822 * an entity for a specific entity type.
4823 *
4824 * @param {Object} props The component's props.
4825 * @param {string} props.kind The entity kind.
4826 * @param {string} props.type The entity type.
4827 * @param {number} props.id The entity ID.
4828 * @param {*} props.children The children to wrap.
4829 *
4830 * @return {Object} The provided children, wrapped with
4831 * the entity's context provider.
4832 */
4833
4834
4835 function EntityProvider({
4836 kind,
4837 type,
4838 id,
4839 children
4840 }) {
4841 const Provider = entity_provider_getEntity(kind, type).context.Provider;
4842 return (0,external_wp_element_namespaceObject.createElement)(Provider, {
4843 value: id
4844 }, children);
4845 }
4846 /**
4847 * Hook that returns the ID for the nearest
4848 * provided entity of the specified type.
4849 *
4850 * @param {string} kind The entity kind.
4851 * @param {string} type The entity type.
4852 */
4853
4854 function useEntityId(kind, type) {
4855 return (0,external_wp_element_namespaceObject.useContext)(entity_provider_getEntity(kind, type).context);
4856 }
4857 /**
4858 * Hook that returns the value and a setter for the
4859 * specified property of the nearest provided
4860 * entity of the specified type.
4861 *
4862 * @param {string} kind The entity kind.
4863 * @param {string} type The entity type.
4864 * @param {string} prop The property name.
4865 * @param {string} [_id] An entity ID to use instead of the context-provided one.
4866 *
4867 * @return {[*, Function, *]} An array where the first item is the
4868 * property value, the second is the
4869 * setter and the third is the full value
4870 * object from REST API containing more
4871 * information like `raw`, `rendered` and
4872 * `protected` props.
4873 */
4874
4875 function useEntityProp(kind, type, prop, _id) {
4876 const providerId = useEntityId(kind, type);
4877 const id = _id !== null && _id !== void 0 ? _id : providerId;
4878 const {
4879 value,
4880 fullValue
4881 } = (0,external_wp_data_namespaceObject.useSelect)(select => {
4882 const {
4883 getEntityRecord,
4884 getEditedEntityRecord
4885 } = select(STORE_NAME);
4886 const entity = getEntityRecord(kind, type, id); // Trigger resolver.
4887
4888 const editedEntity = getEditedEntityRecord(kind, type, id);
4889 return entity && editedEntity ? {
4890 value: editedEntity[prop],
4891 fullValue: entity[prop]
4892 } : {};
4893 }, [kind, type, id, prop]);
4894 const {
4895 editEntityRecord
4896 } = (0,external_wp_data_namespaceObject.useDispatch)(STORE_NAME);
4897 const setValue = (0,external_wp_element_namespaceObject.useCallback)(newValue => {
4898 editEntityRecord(kind, type, id, {
4899 [prop]: newValue
4900 });
4901 }, [kind, type, id, prop]);
4902 return [value, setValue, fullValue];
4903 }
4904 /**
4905 * Hook that returns block content getters and setters for
4906 * the nearest provided entity of the specified type.
4907 *
4908 * The return value has the shape `[ blocks, onInput, onChange ]`.
4909 * `onInput` is for block changes that don't create undo levels
4910 * or dirty the post, non-persistent changes, and `onChange` is for
4911 * peristent changes. They map directly to the props of a
4912 * `BlockEditorProvider` and are intended to be used with it,
4913 * or similar components or hooks.
4914 *
4915 * @param {string} kind The entity kind.
4916 * @param {string} type The entity type.
4917 * @param {Object} options
4918 * @param {string} [options.id] An entity ID to use instead of the context-provided one.
4919 *
4920 * @return {[WPBlock[], Function, Function]} The block array and setters.
4921 */
4922
4923 function useEntityBlockEditor(kind, type, {
4924 id: _id
4925 } = {}) {
4926 const providerId = useEntityId(kind, type);
4927 const id = _id !== null && _id !== void 0 ? _id : providerId;
4928 const {
4929 content,
4930 blocks
4931 } = (0,external_wp_data_namespaceObject.useSelect)(select => {
4932 const {
4933 getEditedEntityRecord
4934 } = select(STORE_NAME);
4935 const editedEntity = getEditedEntityRecord(kind, type, id);
4936 return {
4937 blocks: editedEntity.blocks,
4938 content: editedEntity.content
4939 };
4940 }, [kind, type, id]);
4941 const {
4942 __unstableCreateUndoLevel,
4943 editEntityRecord
4944 } = (0,external_wp_data_namespaceObject.useDispatch)(STORE_NAME);
4945 (0,external_wp_element_namespaceObject.useEffect)(() => {
4946 // Load the blocks from the content if not already in state
4947 // Guard against other instances that might have
4948 // set content to a function already or the blocks are already in state.
4949 if (content && typeof content !== 'function' && !blocks) {
4950 const parsedContent = (0,external_wp_blocks_namespaceObject.parse)(content);
4951 editEntityRecord(kind, type, id, {
4952 blocks: parsedContent
4953 }, {
4954 undoIgnore: true
4955 });
4956 }
4957 }, [content]);
4958 const onChange = (0,external_wp_element_namespaceObject.useCallback)((newBlocks, options) => {
4959 const {
4960 selection
4961 } = options;
4962 const edits = {
4963 blocks: newBlocks,
4964 selection
4965 };
4966 const noChange = blocks === edits.blocks;
4967
4968 if (noChange) {
4969 return __unstableCreateUndoLevel(kind, type, id);
4970 } // We create a new function here on every persistent edit
4971 // to make sure the edit makes the post dirty and creates
4972 // a new undo level.
4973
4974
4975 edits.content = ({
4976 blocks: blocksForSerialization = []
4977 }) => (0,external_wp_blocks_namespaceObject.__unstableSerializeAndClean)(blocksForSerialization);
4978
4979 editEntityRecord(kind, type, id, edits);
4980 }, [kind, type, id, blocks]);
4981 const onInput = (0,external_wp_element_namespaceObject.useCallback)((newBlocks, options) => {
4982 const {
4983 selection
4984 } = options;
4985 const edits = {
4986 blocks: newBlocks,
4987 selection
4988 };
4989 editEntityRecord(kind, type, id, edits);
4990 }, [kind, type, id]);
4991 return [blocks !== null && blocks !== void 0 ? blocks : entity_provider_EMPTY_ARRAY, onInput, onChange];
4992 }
4993 //# sourceMappingURL=entity-provider.js.map
4994 ;// CONCATENATED MODULE: external ["wp","htmlEntities"]
4995 var external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"];
4996 ;// CONCATENATED MODULE: ./packages/core-data/build-module/fetch/__experimental-fetch-link-suggestions.js
4997 /**
4998 * WordPress dependencies
4999 */
5000
5001
5002
5003
5004 /**
5005 * Filters the search by type
5006 *
5007 * @typedef { 'post' | 'term' | 'post-format' } WPLinkSearchType
5008 */
5009
5010 /**
5011 * A link with an id may be of kind post-type or taxonomy
5012 *
5013 * @typedef { 'post-type' | 'taxonomy' } WPKind
5014 */
5015
5016 /**
5017 * @typedef WPLinkSearchOptions
5018 *
5019 * @property {boolean} [isInitialSuggestions] Displays initial search suggestions, when true.
5020 * @property {WPLinkSearchType} [type] Filters by search type.
5021 * @property {string} [subtype] Slug of the post-type or taxonomy.
5022 * @property {number} [page] Which page of results to return.
5023 * @property {number} [perPage] Search results per page.
5024 */
5025
5026 /**
5027 * @typedef WPLinkSearchResult
5028 *
5029 * @property {number} id Post or term id.
5030 * @property {string} url Link url.
5031 * @property {string} title Title of the link.
5032 * @property {string} type The taxonomy or post type slug or type URL.
5033 * @property {WPKind} [kind] Link kind of post-type or taxonomy
5034 */
5035
5036 /**
5037 * @typedef WPEditorSettings
5038 *
5039 * @property {boolean} [ disablePostFormats ] Disables post formats, when true.
5040 */
5041
5042 /**
5043 * Fetches link suggestions from the API.
5044 *
5045 * @async
5046 * @param {string} search
5047 * @param {WPLinkSearchOptions} [searchOptions]
5048 * @param {WPEditorSettings} [settings]
5049 *
5050 * @example
5051 * ```js
5052 * import { __experimentalFetchLinkSuggestions as fetchLinkSuggestions } from '@wordpress/core-data';
5053 *
5054 * //...
5055 *
5056 * export function initialize( id, settings ) {
5057 *
5058 * settings.__experimentalFetchLinkSuggestions = (
5059 * search,
5060 * searchOptions
5061 * ) => fetchLinkSuggestions( search, searchOptions, settings );
5062 * ```
5063 * @return {Promise< WPLinkSearchResult[] >} List of search suggestions
5064 */
5065
5066 const fetchLinkSuggestions = async (search, searchOptions = {}, settings = {}) => {
5067 const {
5068 isInitialSuggestions = false,
5069 type = undefined,
5070 subtype = undefined,
5071 page = undefined,
5072 perPage = isInitialSuggestions ? 3 : 20
5073 } = searchOptions;
5074 const {
5075 disablePostFormats = false
5076 } = settings;
5077 const queries = [];
5078
5079 if (!type || type === 'post') {
5080 queries.push(external_wp_apiFetch_default()({
5081 path: (0,external_wp_url_namespaceObject.addQueryArgs)('/wp/v2/search', {
5082 search,
5083 page,
5084 per_page: perPage,
5085 type: 'post',
5086 subtype
5087 })
5088 }).then(results => {
5089 return results.map(result => {
5090 return { ...result,
5091 meta: {
5092 kind: 'post-type',
5093 subtype
5094 }
5095 };
5096 });
5097 }).catch(() => []) // fail by returning no results
5098 );
5099 }
5100
5101 if (!type || type === 'term') {
5102 queries.push(external_wp_apiFetch_default()({
5103 path: (0,external_wp_url_namespaceObject.addQueryArgs)('/wp/v2/search', {
5104 search,
5105 page,
5106 per_page: perPage,
5107 type: 'term',
5108 subtype
5109 })
5110 }).then(results => {
5111 return results.map(result => {
5112 return { ...result,
5113 meta: {
5114 kind: 'taxonomy',
5115 subtype
5116 }
5117 };
5118 });
5119 }).catch(() => []));
5120 }
5121
5122 if (!disablePostFormats && (!type || type === 'post-format')) {
5123 queries.push(external_wp_apiFetch_default()({
5124 path: (0,external_wp_url_namespaceObject.addQueryArgs)('/wp/v2/search', {
5125 search,
5126 page,
5127 per_page: perPage,
5128 type: 'post-format',
5129 subtype
5130 })
5131 }).then(results => {
5132 return results.map(result => {
5133 return { ...result,
5134 meta: {
5135 kind: 'taxonomy',
5136 subtype
5137 }
5138 };
5139 });
5140 }).catch(() => []));
5141 }
5142
5143 return Promise.all(queries).then(results => {
5144 return results.reduce((accumulator, current) => accumulator.concat(current), //flatten list
5145 []).filter(
5146 /**
5147 * @param {{ id: number }} result
5148 */
5149 result => {
5150 return !!result.id;
5151 }).slice(0, perPage).map(
5152 /**
5153 * @param {{ id: number, url:string, title?:string, subtype?: string, type?: string }} result
5154 */
5155 result => {
5156 var _result$meta;
5157
5158 return {
5159 id: result.id,
5160 url: result.url,
5161 title: (0,external_wp_htmlEntities_namespaceObject.decodeEntities)(result.title || '') || (0,external_wp_i18n_namespaceObject.__)('(no title)'),
5162 type: result.subtype || result.type,
5163 kind: result === null || result === void 0 ? void 0 : (_result$meta = result.meta) === null || _result$meta === void 0 ? void 0 : _result$meta.kind
5164 };
5165 });
5166 });
5167 };
5168
5169 /* harmony default export */ var _experimental_fetch_link_suggestions = (fetchLinkSuggestions);
5170 //# sourceMappingURL=__experimental-fetch-link-suggestions.js.map
5171 ;// CONCATENATED MODULE: ./packages/core-data/build-module/fetch/__experimental-fetch-url-data.js
5172 /**
5173 * WordPress dependencies
5174 */
5175
5176
5177 /**
5178 * A simple in-memory cache for requests.
5179 * This avoids repeat HTTP requests which may be beneficial
5180 * for those wishing to preserve low-bandwidth.
5181 */
5182
5183 const CACHE = new Map();
5184 /**
5185 * @typedef WPRemoteUrlData
5186 *
5187 * @property {string} title contents of the remote URL's `<title>` tag.
5188 */
5189
5190 /**
5191 * Fetches data about a remote URL.
5192 * eg: <title> tag, favicon...etc.
5193 *
5194 * @async
5195 * @param {string} url the URL to request details from.
5196 * @param {Object?} options any options to pass to the underlying fetch.
5197 * @example
5198 * ```js
5199 * import { __experimentalFetchUrlData as fetchUrlData } from '@wordpress/core-data';
5200 *
5201 * //...
5202 *
5203 * export function initialize( id, settings ) {
5204 *
5205 * settings.__experimentalFetchUrlData = (
5206 * url
5207 * ) => fetchUrlData( url );
5208 * ```
5209 * @return {Promise< WPRemoteUrlData[] >} Remote URL data.
5210 */
5211
5212 const fetchUrlData = async (url, options = {}) => {
5213 const endpoint = '/__experimental/url-details';
5214 const args = {
5215 url: (0,external_wp_url_namespaceObject.prependHTTP)(url)
5216 };
5217
5218 if (!(0,external_wp_url_namespaceObject.isURL)(url)) {
5219 return Promise.reject(`${url} is not a valid URL.`);
5220 } // Test for "http" based URL as it is possible for valid
5221 // yet unusable URLs such as `tel:123456` to be passed.
5222
5223
5224 const protocol = (0,external_wp_url_namespaceObject.getProtocol)(url);
5225
5226 if (!(0,external_wp_url_namespaceObject.isValidProtocol)(protocol) || !protocol.startsWith('http') || !/^https?:\/\/[^\/\s]/i.test(url)) {
5227 return Promise.reject(`${url} does not have a valid protocol. URLs must be "http" based`);
5228 }
5229
5230 if (CACHE.has(url)) {
5231 return CACHE.get(url);
5232 }
5233
5234 return external_wp_apiFetch_default()({
5235 path: (0,external_wp_url_namespaceObject.addQueryArgs)(endpoint, args),
5236 ...options
5237 }).then(res => {
5238 CACHE.set(url, res);
5239 return res;
5240 });
5241 };
5242
5243 /* harmony default export */ var _experimental_fetch_url_data = (fetchUrlData);
5244 //# sourceMappingURL=__experimental-fetch-url-data.js.map
5245 ;// CONCATENATED MODULE: ./packages/core-data/build-module/fetch/index.js
5246
5247
5248 //# sourceMappingURL=index.js.map
5249 ;// CONCATENATED MODULE: ./packages/core-data/build-module/index.js
5250 /**
5251 * WordPress dependencies
5252 */
5253
5254 /**
5255 * Internal dependencies
5256 */
5257
5258
5259
5260
5261
5262
5263
5264 // The entity selectors/resolvers and actions are shortcuts to their generic equivalents
5265 // (getEntityRecord, getEntityRecords, updateEntityRecord, updateEntityRecordss)
5266 // Instead of getEntityRecord, the consumer could use more user-frieldly named selector: getPostType, getTaxonomy...
5267 // The "kind" and the "name" of the entity are combined to generate these shortcuts.
5268
5269 const entitySelectors = defaultEntities.reduce((result, entity) => {
5270 const {
5271 kind,
5272 name
5273 } = entity;
5274
5275 result[getMethodName(kind, name)] = (state, key, query) => getEntityRecord(state, kind, name, key, query);
5276
5277 result[getMethodName(kind, name, 'get', true)] = (state, ...args) => getEntityRecords(state, kind, name, ...args);
5278
5279 return result;
5280 }, {});
5281 const entityResolvers = defaultEntities.reduce((result, entity) => {
5282 const {
5283 kind,
5284 name
5285 } = entity;
5286
5287 result[getMethodName(kind, name)] = (key, query) => resolvers_getEntityRecord(kind, name, key, query);
5288
5289 const pluralMethodName = getMethodName(kind, name, 'get', true);
5290
5291 result[pluralMethodName] = (...args) => resolvers_getEntityRecords(kind, name, ...args);
5292
5293 result[pluralMethodName].shouldInvalidate = (action, ...args) => resolvers_getEntityRecords.shouldInvalidate(action, kind, name, ...args);
5294
5295 return result;
5296 }, {});
5297 const entityActions = defaultEntities.reduce((result, entity) => {
5298 const {
5299 kind,
5300 name
5301 } = entity;
5302
5303 result[getMethodName(kind, name, 'save')] = key => saveEntityRecord(kind, name, key);
5304
5305 result[getMethodName(kind, name, 'delete')] = (key, query) => deleteEntityRecord(kind, name, key, query);
5306
5307 return result;
5308 }, {});
5309
5310 const storeConfig = () => ({
5311 reducer: build_module_reducer,
5312 actions: { ...build_module_actions_namespaceObject,
5313 ...entityActions,
5314 ...createLocksActions()
5315 },
5316 selectors: { ...build_module_selectors_namespaceObject,
5317 ...entitySelectors
5318 },
5319 resolvers: { ...resolvers_namespaceObject,
5320 ...entityResolvers
5321 },
5322 __experimentalUseThunks: true
5323 });
5324 /**
5325 * Store definition for the code data namespace.
5326 *
5327 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore
5328 *
5329 * @type {Object}
5330 */
5331
5332
5333 const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, storeConfig());
5334 (0,external_wp_data_namespaceObject.register)(store);
5335
5336
5337
5338 //# sourceMappingURL=index.js.map
5339 }();
5340 (window.wp = window.wp || {}).coreData = __webpack_exports__;
5341 /******/ })()
5342 ;