@wordpress/core-data 4.0.1 → 4.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -7
- package/build/actions.js +178 -122
- package/build/actions.js.map +1 -1
- package/build/batch/default-processor.js +58 -27
- package/build/batch/default-processor.js.map +1 -1
- package/build/entities.js +70 -23
- package/build/entities.js.map +1 -1
- package/build/fetch/__experimental-fetch-url-data.js +1 -1
- package/build/fetch/__experimental-fetch-url-data.js.map +1 -1
- package/build/index.js +9 -17
- package/build/index.js.map +1 -1
- package/build/locks/actions.js +17 -77
- package/build/locks/actions.js.map +1 -1
- package/build/locks/engine.js +77 -0
- package/build/locks/engine.js.map +1 -0
- package/build/locks/reducer.js +1 -5
- package/build/locks/reducer.js.map +1 -1
- package/build/locks/selectors.js +6 -6
- package/build/locks/selectors.js.map +1 -1
- package/build/queried-data/get-query-parts.js +9 -4
- package/build/queried-data/get-query-parts.js.map +1 -1
- package/build/queried-data/selectors.js +3 -9
- package/build/queried-data/selectors.js.map +1 -1
- package/build/reducer.js +17 -22
- package/build/reducer.js.map +1 -1
- package/build/resolvers.js +151 -97
- package/build/resolvers.js.map +1 -1
- package/build/selectors.js +79 -14
- package/build/selectors.js.map +1 -1
- package/build/utils/forward-resolver.js +23 -0
- package/build/utils/forward-resolver.js.map +1 -0
- package/build/utils/index.js +11 -3
- package/build/utils/index.js.map +1 -1
- package/build/utils/is-raw-attribute.js +19 -0
- package/build/utils/is-raw-attribute.js.map +1 -0
- package/build-module/actions.js +155 -112
- package/build-module/actions.js.map +1 -1
- package/build-module/batch/default-processor.js +57 -27
- package/build-module/batch/default-processor.js.map +1 -1
- package/build-module/entities.js +65 -19
- package/build-module/entities.js.map +1 -1
- package/build-module/fetch/__experimental-fetch-url-data.js +1 -1
- package/build-module/fetch/__experimental-fetch-url-data.js.map +1 -1
- package/build-module/index.js +10 -14
- package/build-module/index.js.map +1 -1
- package/build-module/locks/actions.js +14 -68
- package/build-module/locks/actions.js.map +1 -1
- package/build-module/locks/engine.js +66 -0
- package/build-module/locks/engine.js.map +1 -0
- package/build-module/locks/reducer.js +1 -2
- package/build-module/locks/reducer.js.map +1 -1
- package/build-module/locks/selectors.js +4 -4
- package/build-module/locks/selectors.js.map +1 -1
- package/build-module/queried-data/get-query-parts.js +9 -4
- package/build-module/queried-data/get-query-parts.js.map +1 -1
- package/build-module/queried-data/selectors.js +3 -9
- package/build-module/queried-data/selectors.js.map +1 -1
- package/build-module/reducer.js +15 -19
- package/build-module/reducer.js.map +1 -1
- package/build-module/resolvers.js +123 -81
- package/build-module/resolvers.js.map +1 -1
- package/build-module/selectors.js +74 -13
- package/build-module/selectors.js.map +1 -1
- package/build-module/utils/forward-resolver.js +15 -0
- package/build-module/utils/forward-resolver.js.map +1 -0
- package/build-module/utils/index.js +2 -1
- package/build-module/utils/index.js.map +1 -1
- package/build-module/utils/is-raw-attribute.js +12 -0
- package/build-module/utils/is-raw-attribute.js.map +1 -0
- package/package.json +10 -11
- package/src/actions.js +163 -194
- package/src/batch/default-processor.js +57 -26
- package/src/batch/test/default-processor.js +53 -26
- package/src/entities.js +47 -19
- package/src/fetch/__experimental-fetch-url-data.js +1 -1
- package/src/index.js +7 -10
- package/src/locks/actions.js +10 -61
- package/src/locks/engine.js +43 -0
- package/src/locks/reducer.js +1 -3
- package/src/locks/selectors.js +4 -4
- package/src/locks/test/engine.js +135 -0
- package/src/locks/test/reducer.js +1 -1
- package/src/locks/test/selectors.js +105 -124
- package/src/queried-data/get-query-parts.js +11 -6
- package/src/queried-data/selectors.js +2 -9
- package/src/queried-data/test/get-query-parts.js +1 -1
- package/src/queried-data/test/selectors.js +1 -0
- package/src/reducer.js +14 -19
- package/src/resolvers.js +132 -120
- package/src/selectors.js +156 -44
- package/src/test/actions.js +330 -170
- package/src/test/entities.js +40 -26
- package/src/test/resolvers.js +270 -223
- package/src/test/selectors.js +127 -1
- package/src/utils/forward-resolver.js +14 -0
- package/src/utils/index.js +2 -1
- package/src/utils/is-raw-attribute.js +11 -0
- package/src/utils/test/is-raw-attribute.js +22 -0
- package/build/controls.js +0 -44
- package/build/controls.js.map +0 -1
- package/build/locks/index.js +0 -47
- package/build/locks/index.js.map +0 -1
- package/build/utils/if-not-resolved.js +0 -46
- package/build/utils/if-not-resolved.js.map +0 -1
- package/build-module/controls.js +0 -31
- package/build-module/controls.js.map +0 -1
- package/build-module/locks/index.js +0 -4
- package/build-module/locks/index.js.map +0 -1
- package/build-module/utils/if-not-resolved.js +0 -36
- package/build-module/utils/if-not-resolved.js.map +0 -1
- package/src/controls.js +0 -31
- package/src/locks/index.js +0 -3
- package/src/locks/test/actions.js +0 -307
- package/src/test/integration.js +0 -264
- package/src/utils/if-not-resolved.js +0 -40
- package/src/utils/test/if-not-resolved.js +0 -75
package/src/reducer.js
CHANGED
|
@@ -15,7 +15,6 @@ import isShallowEqual from '@wordpress/is-shallow-equal';
|
|
|
15
15
|
import { ifMatchingAction, replaceAction } from './utils';
|
|
16
16
|
import { reducer as queriedDataReducer } from './queried-data';
|
|
17
17
|
import { defaultEntities, DEFAULT_ENTITY_KEY } from './entities';
|
|
18
|
-
import { reducer as locksReducer } from './locks';
|
|
19
18
|
|
|
20
19
|
/**
|
|
21
20
|
* Reducer managing terms state. Keyed by taxonomy slug, the value is either
|
|
@@ -121,39 +120,36 @@ export function currentTheme( state = undefined, action ) {
|
|
|
121
120
|
}
|
|
122
121
|
|
|
123
122
|
/**
|
|
124
|
-
* Reducer managing
|
|
123
|
+
* Reducer managing the current global styles id.
|
|
125
124
|
*
|
|
126
|
-
* @param {
|
|
125
|
+
* @param {string} state Current state.
|
|
127
126
|
* @param {Object} action Dispatched action.
|
|
128
127
|
*
|
|
129
|
-
* @return {
|
|
128
|
+
* @return {string} Updated state.
|
|
130
129
|
*/
|
|
131
|
-
export function
|
|
130
|
+
export function currentGlobalStylesId( state = undefined, action ) {
|
|
132
131
|
switch ( action.type ) {
|
|
133
|
-
case '
|
|
134
|
-
return
|
|
135
|
-
...state,
|
|
136
|
-
[ action.currentTheme.stylesheet ]: action.currentTheme,
|
|
137
|
-
};
|
|
132
|
+
case 'RECEIVE_CURRENT_GLOBAL_STYLES_ID':
|
|
133
|
+
return action.id;
|
|
138
134
|
}
|
|
139
135
|
|
|
140
136
|
return state;
|
|
141
137
|
}
|
|
142
138
|
|
|
143
139
|
/**
|
|
144
|
-
* Reducer managing theme
|
|
140
|
+
* Reducer managing the theme base global styles.
|
|
145
141
|
*
|
|
146
|
-
* @param {
|
|
142
|
+
* @param {string} state Current state.
|
|
147
143
|
* @param {Object} action Dispatched action.
|
|
148
144
|
*
|
|
149
|
-
* @return {
|
|
145
|
+
* @return {string} Updated state.
|
|
150
146
|
*/
|
|
151
|
-
export function
|
|
147
|
+
export function themeBaseGlobalStyles( state = {}, action ) {
|
|
152
148
|
switch ( action.type ) {
|
|
153
|
-
case '
|
|
149
|
+
case 'RECEIVE_THEME_GLOBAL_STYLES':
|
|
154
150
|
return {
|
|
155
151
|
...state,
|
|
156
|
-
|
|
152
|
+
[ action.stylesheet ]: action.globalStyles,
|
|
157
153
|
};
|
|
158
154
|
}
|
|
159
155
|
|
|
@@ -571,14 +567,13 @@ export default combineReducers( {
|
|
|
571
567
|
terms,
|
|
572
568
|
users,
|
|
573
569
|
currentTheme,
|
|
570
|
+
currentGlobalStylesId,
|
|
574
571
|
currentUser,
|
|
572
|
+
themeBaseGlobalStyles,
|
|
575
573
|
taxonomies,
|
|
576
|
-
themes,
|
|
577
|
-
themeSupports,
|
|
578
574
|
entities,
|
|
579
575
|
undo,
|
|
580
576
|
embedPreviews,
|
|
581
577
|
userPermissions,
|
|
582
578
|
autosaves,
|
|
583
|
-
locks: locksReducer,
|
|
584
579
|
} );
|
package/src/resolvers.js
CHANGED
|
@@ -7,33 +7,14 @@ import { find, includes, get, hasIn, compact, uniq } from 'lodash';
|
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
9
|
import { addQueryArgs } from '@wordpress/url';
|
|
10
|
-
import
|
|
11
|
-
import { apiFetch } from '@wordpress/data-controls';
|
|
12
|
-
/**
|
|
13
|
-
* Internal dependencies
|
|
14
|
-
*/
|
|
15
|
-
import { regularFetch } from './controls';
|
|
16
|
-
import { STORE_NAME } from './name';
|
|
10
|
+
import apiFetch from '@wordpress/api-fetch';
|
|
17
11
|
|
|
18
12
|
/**
|
|
19
13
|
* Internal dependencies
|
|
20
14
|
*/
|
|
21
|
-
import {
|
|
22
|
-
receiveUserQuery,
|
|
23
|
-
receiveCurrentTheme,
|
|
24
|
-
receiveCurrentUser,
|
|
25
|
-
receiveEntityRecords,
|
|
26
|
-
receiveThemeSupports,
|
|
27
|
-
receiveEmbedPreview,
|
|
28
|
-
receiveUserPermission,
|
|
29
|
-
receiveAutosaves,
|
|
30
|
-
} from './actions';
|
|
15
|
+
import { STORE_NAME } from './name';
|
|
31
16
|
import { getKindEntities, DEFAULT_ENTITY_KEY } from './entities';
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
__unstableAcquireStoreLock,
|
|
35
|
-
__unstableReleaseStoreLock,
|
|
36
|
-
} from './locks';
|
|
17
|
+
import { forwardResolver, getNormalizedCommaSeparable } from './utils';
|
|
37
18
|
|
|
38
19
|
/**
|
|
39
20
|
* Requests authors from the REST API.
|
|
@@ -41,22 +22,22 @@ import {
|
|
|
41
22
|
* @param {Object|undefined} query Optional object of query parameters to
|
|
42
23
|
* include with request.
|
|
43
24
|
*/
|
|
44
|
-
export
|
|
25
|
+
export const getAuthors = ( query ) => async ( { dispatch } ) => {
|
|
45
26
|
const path = addQueryArgs(
|
|
46
27
|
'/wp/v2/users/?who=authors&per_page=100',
|
|
47
28
|
query
|
|
48
29
|
);
|
|
49
|
-
const users =
|
|
50
|
-
|
|
51
|
-
}
|
|
30
|
+
const users = await apiFetch( { path } );
|
|
31
|
+
dispatch.receiveUserQuery( path, users );
|
|
32
|
+
};
|
|
52
33
|
|
|
53
34
|
/**
|
|
54
35
|
* Requests the current user from the REST API.
|
|
55
36
|
*/
|
|
56
|
-
export
|
|
57
|
-
const currentUser =
|
|
58
|
-
|
|
59
|
-
}
|
|
37
|
+
export const getCurrentUser = () => async ( { dispatch } ) => {
|
|
38
|
+
const currentUser = await apiFetch( { path: '/wp/v2/users/me' } );
|
|
39
|
+
dispatch.receiveCurrentUser( currentUser );
|
|
40
|
+
};
|
|
60
41
|
|
|
61
42
|
/**
|
|
62
43
|
* Requests an entity's record from the REST API.
|
|
@@ -67,18 +48,22 @@ export function* getCurrentUser() {
|
|
|
67
48
|
* @param {Object|undefined} query Optional object of query parameters to
|
|
68
49
|
* include with request.
|
|
69
50
|
*/
|
|
70
|
-
export
|
|
71
|
-
|
|
51
|
+
export const getEntityRecord = ( kind, name, key = '', query ) => async ( {
|
|
52
|
+
select,
|
|
53
|
+
dispatch,
|
|
54
|
+
} ) => {
|
|
55
|
+
const entities = await dispatch( getKindEntities( kind ) );
|
|
72
56
|
const entity = find( entities, { kind, name } );
|
|
73
|
-
if ( ! entity ) {
|
|
57
|
+
if ( ! entity || entity?.__experimentalNoFetch ) {
|
|
74
58
|
return;
|
|
75
59
|
}
|
|
76
60
|
|
|
77
|
-
const lock =
|
|
61
|
+
const lock = await dispatch.__unstableAcquireStoreLock(
|
|
78
62
|
STORE_NAME,
|
|
79
63
|
[ 'entities', 'data', kind, name, key ],
|
|
80
64
|
{ exclusive: false }
|
|
81
65
|
);
|
|
66
|
+
|
|
82
67
|
try {
|
|
83
68
|
if ( query !== undefined && query._fields ) {
|
|
84
69
|
// If requesting specific fields, items and query association to said
|
|
@@ -100,7 +85,7 @@ export function* getEntityRecord( kind, name, key = '', query ) {
|
|
|
100
85
|
// for how the request is made to the REST API.
|
|
101
86
|
|
|
102
87
|
// eslint-disable-next-line @wordpress/no-unused-vars-before-return
|
|
103
|
-
const path = addQueryArgs( entity.baseURL + '/' + key, {
|
|
88
|
+
const path = addQueryArgs( entity.baseURL + ( key ? '/' + key : '' ), {
|
|
104
89
|
...entity.baseURLParams,
|
|
105
90
|
...query,
|
|
106
91
|
} );
|
|
@@ -111,43 +96,31 @@ export function* getEntityRecord( kind, name, key = '', query ) {
|
|
|
111
96
|
// The resolution cache won't consider query as reusable based on the
|
|
112
97
|
// fields, so it's tested here, prior to initiating the REST request,
|
|
113
98
|
// and without causing `getEntityRecords` resolution to occur.
|
|
114
|
-
const hasRecords =
|
|
115
|
-
STORE_NAME,
|
|
116
|
-
'hasEntityRecords',
|
|
117
|
-
kind,
|
|
118
|
-
name,
|
|
119
|
-
query
|
|
120
|
-
);
|
|
99
|
+
const hasRecords = select.hasEntityRecords( kind, name, query );
|
|
121
100
|
if ( hasRecords ) {
|
|
122
101
|
return;
|
|
123
102
|
}
|
|
124
103
|
}
|
|
125
104
|
|
|
126
|
-
const record =
|
|
127
|
-
|
|
105
|
+
const record = await apiFetch( { path } );
|
|
106
|
+
dispatch.receiveEntityRecords( kind, name, record, query );
|
|
128
107
|
} catch ( error ) {
|
|
129
108
|
// We need a way to handle and access REST API errors in state
|
|
130
109
|
// Until then, catching the error ensures the resolver is marked as resolved.
|
|
131
110
|
} finally {
|
|
132
|
-
|
|
111
|
+
dispatch.__unstableReleaseStoreLock( lock );
|
|
133
112
|
}
|
|
134
|
-
}
|
|
113
|
+
};
|
|
135
114
|
|
|
136
115
|
/**
|
|
137
116
|
* Requests an entity's record from the REST API.
|
|
138
117
|
*/
|
|
139
|
-
export const getRawEntityRecord =
|
|
140
|
-
getEntityRecord,
|
|
141
|
-
'getEntityRecord'
|
|
142
|
-
);
|
|
118
|
+
export const getRawEntityRecord = forwardResolver( 'getEntityRecord' );
|
|
143
119
|
|
|
144
120
|
/**
|
|
145
121
|
* Requests an entity's record from the REST API.
|
|
146
122
|
*/
|
|
147
|
-
export const getEditedEntityRecord =
|
|
148
|
-
getRawEntityRecord,
|
|
149
|
-
'getRawEntityRecord'
|
|
150
|
-
);
|
|
123
|
+
export const getEditedEntityRecord = forwardResolver( 'getEntityRecord' );
|
|
151
124
|
|
|
152
125
|
/**
|
|
153
126
|
* Requests the entity's records from the REST API.
|
|
@@ -156,18 +129,21 @@ export const getEditedEntityRecord = ifNotResolved(
|
|
|
156
129
|
* @param {string} name Entity name.
|
|
157
130
|
* @param {Object?} query Query Object.
|
|
158
131
|
*/
|
|
159
|
-
export
|
|
160
|
-
|
|
132
|
+
export const getEntityRecords = ( kind, name, query = {} ) => async ( {
|
|
133
|
+
dispatch,
|
|
134
|
+
} ) => {
|
|
135
|
+
const entities = await dispatch( getKindEntities( kind ) );
|
|
161
136
|
const entity = find( entities, { kind, name } );
|
|
162
|
-
if ( ! entity ) {
|
|
137
|
+
if ( ! entity || entity?.__experimentalNoFetch ) {
|
|
163
138
|
return;
|
|
164
139
|
}
|
|
165
140
|
|
|
166
|
-
const lock =
|
|
141
|
+
const lock = await dispatch.__unstableAcquireStoreLock(
|
|
167
142
|
STORE_NAME,
|
|
168
143
|
[ 'entities', 'data', kind, name ],
|
|
169
144
|
{ exclusive: false }
|
|
170
145
|
);
|
|
146
|
+
|
|
171
147
|
try {
|
|
172
148
|
if ( query._fields ) {
|
|
173
149
|
// If requesting specific fields, items and query association to said
|
|
@@ -187,7 +163,7 @@ export function* getEntityRecords( kind, name, query = {} ) {
|
|
|
187
163
|
...query,
|
|
188
164
|
} );
|
|
189
165
|
|
|
190
|
-
let records = Object.values(
|
|
166
|
+
let records = Object.values( await apiFetch( { path } ) );
|
|
191
167
|
// If we request fields but the result doesn't contain the fields,
|
|
192
168
|
// explicitely set these fields as "undefined"
|
|
193
169
|
// that way we consider the query "fullfilled".
|
|
@@ -203,7 +179,8 @@ export function* getEntityRecords( kind, name, query = {} ) {
|
|
|
203
179
|
} );
|
|
204
180
|
}
|
|
205
181
|
|
|
206
|
-
|
|
182
|
+
dispatch.receiveEntityRecords( kind, name, records, query );
|
|
183
|
+
|
|
207
184
|
// When requesting all fields, the list of results can be used to
|
|
208
185
|
// resolve the `getEntityRecord` selector in addition to `getEntityRecords`.
|
|
209
186
|
// See https://github.com/WordPress/gutenberg/pull/26575
|
|
@@ -213,21 +190,21 @@ export function* getEntityRecords( kind, name, query = {} ) {
|
|
|
213
190
|
.filter( ( record ) => record[ key ] )
|
|
214
191
|
.map( ( record ) => [ kind, name, record[ key ] ] );
|
|
215
192
|
|
|
216
|
-
|
|
193
|
+
dispatch( {
|
|
217
194
|
type: 'START_RESOLUTIONS',
|
|
218
195
|
selectorName: 'getEntityRecord',
|
|
219
196
|
args: resolutionsArgs,
|
|
220
|
-
};
|
|
221
|
-
|
|
197
|
+
} );
|
|
198
|
+
dispatch( {
|
|
222
199
|
type: 'FINISH_RESOLUTIONS',
|
|
223
200
|
selectorName: 'getEntityRecord',
|
|
224
201
|
args: resolutionsArgs,
|
|
225
|
-
};
|
|
202
|
+
} );
|
|
226
203
|
}
|
|
227
204
|
} finally {
|
|
228
|
-
|
|
205
|
+
dispatch.__unstableReleaseStoreLock( lock );
|
|
229
206
|
}
|
|
230
|
-
}
|
|
207
|
+
};
|
|
231
208
|
|
|
232
209
|
getEntityRecords.shouldInvalidate = ( action, kind, name ) => {
|
|
233
210
|
return (
|
|
@@ -241,39 +218,37 @@ getEntityRecords.shouldInvalidate = ( action, kind, name ) => {
|
|
|
241
218
|
/**
|
|
242
219
|
* Requests the current theme.
|
|
243
220
|
*/
|
|
244
|
-
export
|
|
245
|
-
const activeThemes =
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
221
|
+
export const getCurrentTheme = () => async ( { dispatch, resolveSelect } ) => {
|
|
222
|
+
const activeThemes = await resolveSelect.getEntityRecords(
|
|
223
|
+
'root',
|
|
224
|
+
'theme',
|
|
225
|
+
{ status: 'active' }
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
dispatch.receiveCurrentTheme( activeThemes[ 0 ] );
|
|
229
|
+
};
|
|
250
230
|
|
|
251
231
|
/**
|
|
252
232
|
* Requests theme supports data from the index.
|
|
253
233
|
*/
|
|
254
|
-
export
|
|
255
|
-
const activeThemes = yield apiFetch( {
|
|
256
|
-
path: '/wp/v2/themes?status=active',
|
|
257
|
-
} );
|
|
258
|
-
yield receiveThemeSupports( activeThemes[ 0 ].theme_supports );
|
|
259
|
-
}
|
|
234
|
+
export const getThemeSupports = forwardResolver( 'getCurrentTheme' );
|
|
260
235
|
|
|
261
236
|
/**
|
|
262
237
|
* Requests a preview from the from the Embed API.
|
|
263
238
|
*
|
|
264
239
|
* @param {string} url URL to get the preview for.
|
|
265
240
|
*/
|
|
266
|
-
export
|
|
241
|
+
export const getEmbedPreview = ( url ) => async ( { dispatch } ) => {
|
|
267
242
|
try {
|
|
268
|
-
const embedProxyResponse =
|
|
243
|
+
const embedProxyResponse = await apiFetch( {
|
|
269
244
|
path: addQueryArgs( '/oembed/1.0/proxy', { url } ),
|
|
270
245
|
} );
|
|
271
|
-
|
|
246
|
+
dispatch.receiveEmbedPreview( url, embedProxyResponse );
|
|
272
247
|
} catch ( error ) {
|
|
273
248
|
// Embed API 404s if the URL cannot be embedded, so we have to catch the error from the apiRequest here.
|
|
274
|
-
|
|
249
|
+
dispatch.receiveEmbedPreview( url, false );
|
|
275
250
|
}
|
|
276
|
-
}
|
|
251
|
+
};
|
|
277
252
|
|
|
278
253
|
/**
|
|
279
254
|
* Checks whether the current user can perform the given action on the given
|
|
@@ -284,7 +259,7 @@ export function* getEmbedPreview( url ) {
|
|
|
284
259
|
* @param {string} resource REST resource to check, e.g. 'media' or 'posts'.
|
|
285
260
|
* @param {?string} id ID of the rest resource to check.
|
|
286
261
|
*/
|
|
287
|
-
export
|
|
262
|
+
export const canUser = ( action, resource, id ) => async ( { dispatch } ) => {
|
|
288
263
|
const methods = {
|
|
289
264
|
create: 'POST',
|
|
290
265
|
read: 'GET',
|
|
@@ -301,7 +276,7 @@ export function* canUser( action, resource, id ) {
|
|
|
301
276
|
|
|
302
277
|
let response;
|
|
303
278
|
try {
|
|
304
|
-
response =
|
|
279
|
+
response = await apiFetch( {
|
|
305
280
|
path,
|
|
306
281
|
// Ideally this would always be an OPTIONS request, but unfortunately there's
|
|
307
282
|
// a bug in the REST API which causes the Allow header to not be sent on
|
|
@@ -329,8 +304,8 @@ export function* canUser( action, resource, id ) {
|
|
|
329
304
|
|
|
330
305
|
const key = compact( [ action, resource, id ] ).join( '/' );
|
|
331
306
|
const isAllowed = includes( allowHeader, method );
|
|
332
|
-
|
|
333
|
-
}
|
|
307
|
+
dispatch.receiveUserPermission( key, isAllowed );
|
|
308
|
+
};
|
|
334
309
|
|
|
335
310
|
/**
|
|
336
311
|
* Checks whether the current user can perform the given action on the given
|
|
@@ -340,16 +315,18 @@ export function* canUser( action, resource, id ) {
|
|
|
340
315
|
* @param {string} name Entity name.
|
|
341
316
|
* @param {string} recordId Record's id.
|
|
342
317
|
*/
|
|
343
|
-
export
|
|
344
|
-
|
|
318
|
+
export const canUserEditEntityRecord = ( kind, name, recordId ) => async ( {
|
|
319
|
+
dispatch,
|
|
320
|
+
} ) => {
|
|
321
|
+
const entities = await dispatch( getKindEntities( kind ) );
|
|
345
322
|
const entity = find( entities, { kind, name } );
|
|
346
323
|
if ( ! entity ) {
|
|
347
324
|
return;
|
|
348
325
|
}
|
|
349
326
|
|
|
350
327
|
const resource = entity.__unstable_rest_base;
|
|
351
|
-
|
|
352
|
-
}
|
|
328
|
+
await dispatch( canUser( 'update', resource, recordId ) );
|
|
329
|
+
};
|
|
353
330
|
|
|
354
331
|
/**
|
|
355
332
|
* Request autosave data from the REST API.
|
|
@@ -357,20 +334,19 @@ export function* canUserEditEntityRecord( kind, name, recordId ) {
|
|
|
357
334
|
* @param {string} postType The type of the parent post.
|
|
358
335
|
* @param {number} postId The id of the parent post.
|
|
359
336
|
*/
|
|
360
|
-
export
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
const autosaves = yield apiFetch( {
|
|
337
|
+
export const getAutosaves = ( postType, postId ) => async ( {
|
|
338
|
+
dispatch,
|
|
339
|
+
resolveSelect,
|
|
340
|
+
} ) => {
|
|
341
|
+
const { rest_base: restBase } = await resolveSelect.getPostType( postType );
|
|
342
|
+
const autosaves = await apiFetch( {
|
|
367
343
|
path: `/wp/v2/${ restBase }/${ postId }/autosaves?context=edit`,
|
|
368
344
|
} );
|
|
369
345
|
|
|
370
346
|
if ( autosaves && autosaves.length ) {
|
|
371
|
-
|
|
347
|
+
dispatch.receiveAutosaves( postId, autosaves );
|
|
372
348
|
}
|
|
373
|
-
}
|
|
349
|
+
};
|
|
374
350
|
|
|
375
351
|
/**
|
|
376
352
|
* Request autosave data from the REST API.
|
|
@@ -381,31 +357,30 @@ export function* getAutosaves( postType, postId ) {
|
|
|
381
357
|
* @param {string} postType The type of the parent post.
|
|
382
358
|
* @param {number} postId The id of the parent post.
|
|
383
359
|
*/
|
|
384
|
-
export
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
postId
|
|
390
|
-
);
|
|
391
|
-
}
|
|
360
|
+
export const getAutosave = ( postType, postId ) => async ( {
|
|
361
|
+
resolveSelect,
|
|
362
|
+
} ) => {
|
|
363
|
+
await resolveSelect.getAutosaves( postType, postId );
|
|
364
|
+
};
|
|
392
365
|
|
|
393
366
|
/**
|
|
394
367
|
* Retrieve the frontend template used for a given link.
|
|
395
368
|
*
|
|
396
369
|
* @param {string} link Link.
|
|
397
370
|
*/
|
|
398
|
-
export
|
|
371
|
+
export const __experimentalGetTemplateForLink = ( link ) => async ( {
|
|
372
|
+
dispatch,
|
|
373
|
+
resolveSelect,
|
|
374
|
+
} ) => {
|
|
399
375
|
// Ideally this should be using an apiFetch call
|
|
400
376
|
// We could potentially do so by adding a "filter" to the `wp_template` end point.
|
|
401
377
|
// Also it seems the returned object is not a regular REST API post type.
|
|
402
378
|
let template;
|
|
403
379
|
try {
|
|
404
|
-
template =
|
|
405
|
-
addQueryArgs( link, {
|
|
406
|
-
|
|
407
|
-
} )
|
|
408
|
-
);
|
|
380
|
+
template = await window
|
|
381
|
+
.fetch( addQueryArgs( link, { '_wp-find-template': true } ) )
|
|
382
|
+
.then( ( res ) => res.json() )
|
|
383
|
+
.then( ( { data } ) => data );
|
|
409
384
|
} catch ( e ) {
|
|
410
385
|
// For non-FSE themes, it is possible that this request returns an error.
|
|
411
386
|
}
|
|
@@ -414,21 +389,18 @@ export function* __experimentalGetTemplateForLink( link ) {
|
|
|
414
389
|
return;
|
|
415
390
|
}
|
|
416
391
|
|
|
417
|
-
|
|
418
|
-
const record = yield controls.select(
|
|
419
|
-
STORE_NAME,
|
|
420
|
-
'getEntityRecord',
|
|
392
|
+
const record = await resolveSelect.getEntityRecord(
|
|
421
393
|
'postType',
|
|
422
394
|
'wp_template',
|
|
423
395
|
template.id
|
|
424
396
|
);
|
|
425
397
|
|
|
426
398
|
if ( record ) {
|
|
427
|
-
|
|
399
|
+
dispatch.receiveEntityRecords( 'postType', 'wp_template', [ record ], {
|
|
428
400
|
'find-template': link,
|
|
429
401
|
} );
|
|
430
402
|
}
|
|
431
|
-
}
|
|
403
|
+
};
|
|
432
404
|
|
|
433
405
|
__experimentalGetTemplateForLink.shouldInvalidate = ( action ) => {
|
|
434
406
|
return (
|
|
@@ -438,3 +410,43 @@ __experimentalGetTemplateForLink.shouldInvalidate = ( action ) => {
|
|
|
438
410
|
action.name === 'wp_template'
|
|
439
411
|
);
|
|
440
412
|
};
|
|
413
|
+
|
|
414
|
+
export const __experimentalGetCurrentGlobalStylesId = () => async ( {
|
|
415
|
+
dispatch,
|
|
416
|
+
resolveSelect,
|
|
417
|
+
} ) => {
|
|
418
|
+
const activeThemes = await resolveSelect.getEntityRecords(
|
|
419
|
+
'root',
|
|
420
|
+
'theme',
|
|
421
|
+
{ status: 'active' }
|
|
422
|
+
);
|
|
423
|
+
const globalStylesURL = get( activeThemes, [
|
|
424
|
+
0,
|
|
425
|
+
'_links',
|
|
426
|
+
'wp:user-global-styles',
|
|
427
|
+
0,
|
|
428
|
+
'href',
|
|
429
|
+
] );
|
|
430
|
+
if ( globalStylesURL ) {
|
|
431
|
+
const globalStylesObject = await apiFetch( {
|
|
432
|
+
url: globalStylesURL,
|
|
433
|
+
} );
|
|
434
|
+
dispatch.__experimentalReceiveCurrentGlobalStylesId(
|
|
435
|
+
globalStylesObject.id
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
export const __experimentalGetCurrentThemeBaseGlobalStyles = () => async ( {
|
|
441
|
+
resolveSelect,
|
|
442
|
+
dispatch,
|
|
443
|
+
} ) => {
|
|
444
|
+
const currentTheme = await resolveSelect.getCurrentTheme();
|
|
445
|
+
const themeGlobalStyles = await apiFetch( {
|
|
446
|
+
path: `/wp/v2/global-styles/themes/${ currentTheme.stylesheet }`,
|
|
447
|
+
} );
|
|
448
|
+
await dispatch.__experimentalReceiveThemeBaseGlobalStyles(
|
|
449
|
+
currentTheme.stylesheet,
|
|
450
|
+
themeGlobalStyles
|
|
451
|
+
);
|
|
452
|
+
};
|