@wordpress/core-data 4.6.0 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/README.md +209 -119
  3. package/build/actions.js.map +1 -1
  4. package/build/batch/create-batch.js +1 -1
  5. package/build/batch/create-batch.js.map +1 -1
  6. package/build/entities.js +49 -35
  7. package/build/entities.js.map +1 -1
  8. package/build/entity-provider.js.map +1 -1
  9. package/build/entity-types/entities.js +6 -0
  10. package/build/entity-types/entities.js.map +1 -0
  11. package/build/hooks/constants.js +0 -2
  12. package/build/hooks/constants.js.map +1 -1
  13. package/build/hooks/index.js +38 -0
  14. package/build/hooks/index.js.map +1 -0
  15. package/build/hooks/use-entity-record.js +22 -8
  16. package/build/hooks/use-entity-record.js.map +1 -1
  17. package/build/hooks/use-entity-records.js +21 -8
  18. package/build/hooks/use-entity-records.js.map +1 -1
  19. package/build/hooks/use-query-select.js.map +1 -1
  20. package/build/index.js +17 -21
  21. package/build/index.js.map +1 -1
  22. package/build/queried-data/selectors.js.map +1 -1
  23. package/build/resolvers.js.map +1 -1
  24. package/build/selectors.js +206 -169
  25. package/build/selectors.js.map +1 -1
  26. package/build/utils/forward-resolver.js.map +1 -1
  27. package/build/utils/on-sub-key.js.map +1 -1
  28. package/build/utils/with-weak-map-cache.js +1 -7
  29. package/build/utils/with-weak-map-cache.js.map +1 -1
  30. package/build-module/actions.js.map +1 -1
  31. package/build-module/batch/create-batch.js +2 -2
  32. package/build-module/batch/create-batch.js.map +1 -1
  33. package/build-module/entities.js +49 -35
  34. package/build-module/entities.js.map +1 -1
  35. package/build-module/entity-provider.js.map +1 -1
  36. package/build-module/entity-types/entities.js +2 -0
  37. package/build-module/entity-types/entities.js.map +1 -0
  38. package/build-module/hooks/constants.js +0 -1
  39. package/build-module/hooks/constants.js.map +1 -1
  40. package/build-module/hooks/index.js +3 -0
  41. package/build-module/hooks/index.js.map +1 -0
  42. package/build-module/hooks/use-entity-record.js +18 -7
  43. package/build-module/hooks/use-entity-record.js.map +1 -1
  44. package/build-module/hooks/use-entity-records.js +17 -7
  45. package/build-module/hooks/use-entity-records.js.map +1 -1
  46. package/build-module/hooks/use-query-select.js.map +1 -1
  47. package/build-module/index.js +2 -3
  48. package/build-module/index.js.map +1 -1
  49. package/build-module/queried-data/selectors.js.map +1 -1
  50. package/build-module/resolvers.js.map +1 -1
  51. package/build-module/selectors.js +203 -166
  52. package/build-module/selectors.js.map +1 -1
  53. package/build-module/utils/forward-resolver.js.map +1 -1
  54. package/build-module/utils/on-sub-key.js.map +1 -1
  55. package/build-module/utils/with-weak-map-cache.js +1 -6
  56. package/build-module/utils/with-weak-map-cache.js.map +1 -1
  57. package/package.json +12 -12
  58. package/src/actions.js +389 -372
  59. package/src/batch/create-batch.js +2 -2
  60. package/src/entities.ts +357 -135
  61. package/src/entity-provider.js +4 -6
  62. package/src/entity-types/attachment.ts +4 -3
  63. package/src/entity-types/comment.ts +4 -3
  64. package/src/entity-types/entities.ts +130 -0
  65. package/src/entity-types/index.ts +115 -20
  66. package/src/entity-types/menu-location.ts +4 -3
  67. package/src/entity-types/nav-menu-item.ts +4 -3
  68. package/src/entity-types/nav-menu.ts +3 -3
  69. package/src/entity-types/page.ts +3 -3
  70. package/src/entity-types/plugin.ts +3 -3
  71. package/src/entity-types/post.ts +3 -3
  72. package/src/entity-types/settings.ts +3 -3
  73. package/src/entity-types/sidebar.ts +4 -3
  74. package/src/entity-types/taxonomy.ts +4 -3
  75. package/src/entity-types/theme.ts +3 -3
  76. package/src/entity-types/type.ts +3 -3
  77. package/src/entity-types/user.ts +3 -3
  78. package/src/entity-types/widget-type.ts +4 -3
  79. package/src/entity-types/widget.ts +3 -3
  80. package/src/entity-types/wp-template-part.ts +4 -3
  81. package/src/entity-types/wp-template.ts +4 -3
  82. package/src/fetch/test/__experimental-fetch-link-suggestions.js +2 -4
  83. package/src/hooks/constants.ts +1 -2
  84. package/src/hooks/index.ts +8 -0
  85. package/src/hooks/test/use-query-select.js +4 -2
  86. package/src/hooks/use-entity-record.ts +31 -9
  87. package/src/hooks/use-entity-records.ts +28 -30
  88. package/src/hooks/use-query-select.ts +26 -24
  89. package/src/index.js +2 -3
  90. package/src/locks/test/selectors.js +2 -1
  91. package/src/queried-data/selectors.js +2 -8
  92. package/src/resolvers.js +344 -325
  93. package/src/selectors.ts +639 -296
  94. package/src/test/resolvers.js +1 -3
  95. package/src/test/selectors.js +1 -2
  96. package/src/utils/forward-resolver.js +6 -5
  97. package/src/utils/on-sub-key.js +20 -20
  98. package/src/utils/with-weak-map-cache.js +1 -6
package/src/selectors.ts CHANGED
@@ -18,6 +18,84 @@ import { STORE_NAME } from './name';
18
18
  import { getQueriedItems } from './queried-data';
19
19
  import { DEFAULT_ENTITY_KEY } from './entities';
20
20
  import { getNormalizedCommaSeparable, isRawAttribute } from './utils';
21
+ import type {
22
+ Context,
23
+ DefaultContextOf,
24
+ EntityRecordOf,
25
+ KeyOf,
26
+ Kind,
27
+ KindOf,
28
+ Name,
29
+ NameOf,
30
+ User,
31
+ WpTemplate,
32
+ } from './entity-types';
33
+
34
+ // This is an incomplete, high-level approximation of the State type.
35
+ // It makes the selectors slightly more safe, but is intended to evolve
36
+ // into a more detailed representation over time.
37
+ // See https://github.com/WordPress/gutenberg/pull/40025#discussion_r865410589 for more context.
38
+ interface State {
39
+ autosaves: Record< string | number, Array< unknown > >;
40
+ blockPatterns: Array< unknown >;
41
+ blockPatternCategories: Array< unknown >;
42
+ currentGlobalStylesId: string;
43
+ currentTheme: string;
44
+ currentUser: User< 'edit' >;
45
+ embedPreviews: Record< string, { html: string } >;
46
+ entities: EntitiesState;
47
+ themeBaseGlobalStyles: Record< string, Object >;
48
+ themeGlobalStyleVariations: Record< string, string >;
49
+ undo: UndoState;
50
+ users: UserState;
51
+ }
52
+
53
+ interface EntitiesState {
54
+ config: EntityConfig[];
55
+ records: Record< Kind, Record< Name, EntityState< Kind, Name > > >;
56
+ }
57
+
58
+ interface EntityState< K extends Kind, N extends Name > {
59
+ edits: Record< KeyOf< K, N >, Partial< EntityRecordOf< K, N > > >;
60
+ saving: Record< KeyOf< K, N >, { pending: boolean } >;
61
+ }
62
+
63
+ interface EntityConfig {
64
+ name: Name;
65
+ kind: Kind;
66
+ }
67
+
68
+ interface UndoState extends Array< Object > {
69
+ flattenedUndo: unknown;
70
+ offset: number;
71
+ }
72
+
73
+ interface UserState {
74
+ queries: Record< string, GenericRecordKey[] >;
75
+ byId: Record< GenericRecordKey, User< 'edit' > >;
76
+ }
77
+
78
+ type GenericRecordKey = number | string;
79
+ type EntityRecord = any;
80
+ type Optional< T > = T | undefined;
81
+
82
+ /**
83
+ * HTTP Query parameters sent with the API request to fetch the entity records.
84
+ */
85
+ export type EntityQuery<
86
+ C extends Context,
87
+ WithFields extends boolean = true
88
+ > = Omit< Record< string, any >, '_fields' > & {
89
+ context?: C;
90
+ } & ( WithFields extends true
91
+ ? {
92
+ /**
93
+ * The requested fields. If specified, the REST API will remove from the response
94
+ * any fields not on that list.
95
+ */
96
+ _fields: string[];
97
+ }
98
+ : {} );
21
99
 
22
100
  /**
23
101
  * Shared reference to an empty object for cases where it is important to avoid
@@ -32,15 +110,18 @@ const EMPTY_OBJECT = {};
32
110
  * Returns true if a request is in progress for embed preview data, or false
33
111
  * otherwise.
34
112
  *
35
- * @param {Object} state Data state.
36
- * @param {string} url URL the preview would be for.
113
+ * @param state Data state.
114
+ * @param url URL the preview would be for.
37
115
  *
38
- * @return {boolean} Whether a request is in progress for an embed preview.
116
+ * @return Whether a request is in progress for an embed preview.
39
117
  */
40
118
  export const isRequestingEmbedPreview = createRegistrySelector(
41
- ( select ) => ( state, url ) => {
42
- return select( STORE_NAME ).isResolving( 'getEmbedPreview', [ url ] );
43
- }
119
+ ( select ) =>
120
+ ( state: State, url: string ): boolean => {
121
+ return select( STORE_NAME ).isResolving( 'getEmbedPreview', [
122
+ url,
123
+ ] );
124
+ }
44
125
  );
45
126
 
46
127
  /**
@@ -48,12 +129,15 @@ export const isRequestingEmbedPreview = createRegistrySelector(
48
129
  *
49
130
  * @deprecated since 11.3. Callers should use `select( 'core' ).getUsers({ who: 'authors' })` instead.
50
131
  *
51
- * @param {Object} state Data state.
52
- * @param {Object|undefined} query Optional object of query parameters to
53
- * include with request.
54
- * @return {Array} Authors list.
132
+ * @param state Data state.
133
+ * @param query Optional object of query parameters to
134
+ * include with request.
135
+ * @return Authors list.
55
136
  */
56
- export function getAuthors( state, query ) {
137
+ export function getAuthors(
138
+ state: State,
139
+ query?: EntityQuery< any >
140
+ ): User< 'edit' >[] {
57
141
  deprecated( "select( 'core' ).getAuthors()", {
58
142
  since: '5.9',
59
143
  alternative: "select( 'core' ).getUsers({ who: 'authors' })",
@@ -69,41 +153,44 @@ export function getAuthors( state, query ) {
69
153
  /**
70
154
  * Returns the current user.
71
155
  *
72
- * @param {Object} state Data state.
156
+ * @param state Data state.
73
157
  *
74
- * @return {Object} Current user object.
158
+ * @return Current user object.
75
159
  */
76
- export function getCurrentUser( state ) {
160
+ export function getCurrentUser( state: State ): User< 'edit' > {
77
161
  return state.currentUser;
78
162
  }
79
163
 
80
164
  /**
81
165
  * Returns all the users returned by a query ID.
82
166
  *
83
- * @param {Object} state Data state.
84
- * @param {string} queryID Query ID.
167
+ * @param state Data state.
168
+ * @param queryID Query ID.
85
169
  *
86
- * @return {Array} Users list.
170
+ * @return Users list.
87
171
  */
88
172
  export const getUserQueryResults = createSelector(
89
- ( state, queryID ) => {
173
+ ( state: State, queryID: string ): User< 'edit' >[] => {
90
174
  const queryResults = state.users.queries[ queryID ];
91
175
 
92
176
  return map( queryResults, ( id ) => state.users.byId[ id ] );
93
177
  },
94
- ( state, queryID ) => [ state.users.queries[ queryID ], state.users.byId ]
178
+ ( state: State, queryID: string ) => [
179
+ state.users.queries[ queryID ],
180
+ state.users.byId,
181
+ ]
95
182
  );
96
183
 
97
184
  /**
98
185
  * Returns the loaded entities for the given kind.
99
186
  *
100
187
  * @deprecated since WordPress 6.0. Use getEntitiesConfig instead
101
- * @param {Object} state Data state.
102
- * @param {string} kind Entity kind.
188
+ * @param state Data state.
189
+ * @param kind Entity kind.
103
190
  *
104
- * @return {Array<Object>} Array of entities with config matching kind.
191
+ * @return Array of entities with config matching kind.
105
192
  */
106
- export function getEntitiesByKind( state, kind ) {
193
+ export function getEntitiesByKind( state: State, kind: Kind ): Array< any > {
107
194
  deprecated( "wp.data.select( 'core' ).getEntitiesByKind()", {
108
195
  since: '6.0',
109
196
  alternative: "wp.data.select( 'core' ).getEntitiesConfig()",
@@ -114,12 +201,12 @@ export function getEntitiesByKind( state, kind ) {
114
201
  /**
115
202
  * Returns the loaded entities for the given kind.
116
203
  *
117
- * @param {Object} state Data state.
118
- * @param {string} kind Entity kind.
204
+ * @param state Data state.
205
+ * @param kind Entity kind.
119
206
  *
120
- * @return {Array<Object>} Array of entities with config matching kind.
207
+ * @return Array of entities with config matching kind.
121
208
  */
122
- export function getEntitiesConfig( state, kind ) {
209
+ export function getEntitiesConfig( state: State, kind: Kind ): Array< any > {
123
210
  return filter( state.entities.config, { kind } );
124
211
  }
125
212
 
@@ -127,13 +214,13 @@ export function getEntitiesConfig( state, kind ) {
127
214
  * Returns the entity config given its kind and name.
128
215
  *
129
216
  * @deprecated since WordPress 6.0. Use getEntityConfig instead
130
- * @param {Object} state Data state.
131
- * @param {string} kind Entity kind.
132
- * @param {string} name Entity name.
217
+ * @param state Data state.
218
+ * @param kind Entity kind.
219
+ * @param name Entity name.
133
220
  *
134
- * @return {Object} Entity config
221
+ * @return Entity config
135
222
  */
136
- export function getEntity( state, kind, name ) {
223
+ export function getEntity( state: State, kind: Kind, name: Name ): any {
137
224
  deprecated( "wp.data.select( 'core' ).getEntity()", {
138
225
  since: '6.0',
139
226
  alternative: "wp.data.select( 'core' ).getEntityConfig()",
@@ -144,31 +231,88 @@ export function getEntity( state, kind, name ) {
144
231
  /**
145
232
  * Returns the entity config given its kind and name.
146
233
  *
147
- * @param {Object} state Data state.
148
- * @param {string} kind Entity kind.
149
- * @param {string} name Entity name.
234
+ * @param state Data state.
235
+ * @param kind Entity kind.
236
+ * @param name Entity name.
150
237
  *
151
- * @return {Object} Entity config
238
+ * @return Entity config
152
239
  */
153
- export function getEntityConfig( state, kind, name ) {
240
+ export function getEntityConfig( state: State, kind: Kind, name: Name ): any {
154
241
  return find( state.entities.config, { kind, name } );
155
242
  }
156
243
 
244
+ /**
245
+ * GetEntityRecord is declared as an *interface*, but it actually describes
246
+ * the specifies the getEntityRecord *function* signature. It may seem unusual,
247
+ * but it's just how TypeScript implements function overloading.
248
+ *
249
+ * More accurately, GetEntityRecord distinguishes between two different signatures
250
+ * the getEntityRecord selector has:
251
+ *
252
+ * 1. When query._fields is not given, the returned type is EntityRecordOf< K, N, C >
253
+ * 2. When query._fields is given, the returned type is Partial<EntityRecordOf< K, N, C >>
254
+ *
255
+ * Unfortunately, due to a TypeScript limitation (https://github.com/microsoft/TypeScript/issues/23132)
256
+ * we can't use a single function signature with a return type such as:
257
+ *
258
+ * Fields extends undefined
259
+ * ? EntityRecordOf< K, N, C >
260
+ * : Partial< EntityRecordOf< K, N, C > >
261
+ */
262
+ interface GetEntityRecord {
263
+ <
264
+ R extends EntityRecordOf< K, N >,
265
+ C extends Context = DefaultContextOf< R >,
266
+ K extends Kind = KindOf< R >,
267
+ N extends Name = NameOf< R >
268
+ >(
269
+ state: State,
270
+ kind: K,
271
+ name: N,
272
+ key: KeyOf< K, N >,
273
+ query: EntityQuery< C, true >
274
+ ): Partial< EntityRecordOf< K, N, C > > | null | undefined;
275
+
276
+ <
277
+ R extends EntityRecordOf< K, N >,
278
+ C extends Context = DefaultContextOf< R >,
279
+ K extends Kind = KindOf< R >,
280
+ N extends Name = NameOf< R >
281
+ >(
282
+ state: State,
283
+ kind: K,
284
+ name: N,
285
+ key: KeyOf< K, N >,
286
+ query?: EntityQuery< C, false >
287
+ ): EntityRecordOf< K, N, C > | null | undefined;
288
+ }
289
+
157
290
  /**
158
291
  * Returns the Entity's record object by key. Returns `null` if the value is not
159
292
  * yet received, undefined if the value entity is known to not exist, or the
160
293
  * entity object if it exists and is received.
161
294
  *
162
- * @param {Object} state State tree
163
- * @param {string} kind Entity kind.
164
- * @param {string} name Entity name.
165
- * @param {number} key Record's key
166
- * @param {?Object} query Optional query.
295
+ * @param state State tree
296
+ * @param kind Entity kind.
297
+ * @param name Entity name.
298
+ * @param key Record's key
299
+ * @param query Optional query.
167
300
  *
168
- * @return {Object|undefined} Record.
301
+ * @return Record.
169
302
  */
170
- export const getEntityRecord = createSelector(
171
- ( state, kind, name, key, query ) => {
303
+ export const getEntityRecord: GetEntityRecord = createSelector(
304
+ <
305
+ R extends EntityRecordOf< K, N >,
306
+ C extends Context = DefaultContextOf< R >,
307
+ K extends Kind = KindOf< R >,
308
+ N extends Name = NameOf< R >
309
+ >(
310
+ state: State,
311
+ kind: K,
312
+ name: N,
313
+ key: KeyOf< R >,
314
+ query
315
+ ) => {
172
316
  const queriedState = get( state.entities.records, [
173
317
  kind,
174
318
  name,
@@ -202,7 +346,7 @@ export const getEntityRecord = createSelector(
202
346
 
203
347
  return item;
204
348
  },
205
- ( state, kind, name, recordId, query ) => {
349
+ ( state: State, kind, name, recordId, query ) => {
206
350
  const context = query?.context ?? 'default';
207
351
  return [
208
352
  get( state.entities.records, [
@@ -228,19 +372,17 @@ export const getEntityRecord = createSelector(
228
372
  /**
229
373
  * Returns the Entity's record object by key. Doesn't trigger a resolver nor requests the entity records from the API if the entity record isn't available in the local state.
230
374
  *
231
- * @param {Object} state State tree
232
- * @param {string} kind Entity kind.
233
- * @param {string} name Entity name.
234
- * @param {number} key Record's key
375
+ * @param state State tree
376
+ * @param kind Entity kind.
377
+ * @param name Entity name.
378
+ * @param key Record's key
235
379
  *
236
- * @return {Object|null} Record.
380
+ * @return Record.
237
381
  */
238
- export function __experimentalGetEntityRecordNoResolver(
239
- state,
240
- kind,
241
- name,
242
- key
243
- ) {
382
+ export function __experimentalGetEntityRecordNoResolver<
383
+ K extends Kind,
384
+ N extends Name
385
+ >( state: State, kind: K, name: N, key: KeyOf< K, N > ) {
244
386
  return getEntityRecord( state, kind, name, key );
245
387
  }
246
388
 
@@ -248,15 +390,20 @@ export function __experimentalGetEntityRecordNoResolver(
248
390
  * Returns the entity's record object by key,
249
391
  * with its attributes mapped to their raw values.
250
392
  *
251
- * @param {Object} state State tree.
252
- * @param {string} kind Entity kind.
253
- * @param {string} name Entity name.
254
- * @param {number} key Record's key.
393
+ * @param state State tree.
394
+ * @param kind Entity kind.
395
+ * @param name Entity name.
396
+ * @param key Record's key.
255
397
  *
256
- * @return {Object?} Object with the entity's raw attributes.
398
+ * @return Object with the entity's raw attributes.
257
399
  */
258
400
  export const getRawEntityRecord = createSelector(
259
- ( state, kind, name, key ) => {
401
+ < K extends Kind, N extends Name >(
402
+ state: State,
403
+ kind: K,
404
+ name: N,
405
+ key: KeyOf< K, N >
406
+ ): EntityRecord | undefined => {
260
407
  const record = getEntityRecord( state, kind, name, key );
261
408
  return (
262
409
  record &&
@@ -279,7 +426,13 @@ export const getRawEntityRecord = createSelector(
279
426
  }, {} )
280
427
  );
281
428
  },
282
- ( state, kind, name, recordId, query ) => {
429
+ (
430
+ state: State,
431
+ kind: Kind,
432
+ name: Name,
433
+ recordId: GenericRecordKey,
434
+ query?: EntityQuery< any >
435
+ ) => {
283
436
  const context = query?.context ?? 'default';
284
437
  return [
285
438
  state.entities.config,
@@ -307,28 +460,87 @@ export const getRawEntityRecord = createSelector(
307
460
  * Returns true if records have been received for the given set of parameters,
308
461
  * or false otherwise.
309
462
  *
310
- * @param {Object} state State tree
311
- * @param {string} kind Entity kind.
312
- * @param {string} name Entity name.
313
- * @param {?Object} query Optional terms query.
463
+ * @param state State tree
464
+ * @param kind Entity kind.
465
+ * @param name Entity name.
466
+ * @param query Optional terms query.
314
467
  *
315
- * @return {boolean} Whether entity records have been received.
468
+ * @return Whether entity records have been received.
316
469
  */
317
- export function hasEntityRecords( state, kind, name, query ) {
470
+ export function hasEntityRecords<
471
+ R extends EntityRecordOf< K, N >,
472
+ C extends Context = DefaultContextOf< R >,
473
+ K extends Kind = KindOf< R >,
474
+ N extends Name = NameOf< R >
475
+ >( state: State, kind: K, name: N, query?: EntityQuery< C > ): boolean {
318
476
  return Array.isArray( getEntityRecords( state, kind, name, query ) );
319
477
  }
320
478
 
479
+ /**
480
+ * GetEntityRecord is declared as an *interface*, but it actually describes
481
+ * the specifies the getEntityRecord *function* signature. It may seem unusual,
482
+ * but it's just how TypeScript implements function overloading.
483
+ *
484
+ * More accurately, GetEntityRecord distinguishes between two different signatures
485
+ * the getEntityRecord selector has:
486
+ *
487
+ * 1. When query._fields is not given, the returned type is EntityRecordOf< K, N, C >[]
488
+ * 2. When query._fields is given, the returned type is Partial<EntityRecordOf< K, N, C >>[]
489
+ *
490
+ * Unfortunately, due to a TypeScript limitation (https://github.com/microsoft/TypeScript/issues/23132)
491
+ * we can't use a single function signature with a return type such as:
492
+ *
493
+ * Fields extends undefined
494
+ * ? EntityRecordOf< K, N, C >[]
495
+ * : Partial< EntityRecordOf< K, N, C > >[]
496
+ */
497
+ interface GetEntityRecords {
498
+ <
499
+ R extends EntityRecordOf< K, N >,
500
+ C extends Context = DefaultContextOf< R >,
501
+ K extends Kind = KindOf< R >,
502
+ N extends Name = NameOf< R >
503
+ >(
504
+ state: State,
505
+ kind: K,
506
+ name: N,
507
+ query: EntityQuery< C, true >
508
+ ): Partial< EntityRecordOf< K, N, C > >[] | null | undefined;
509
+
510
+ <
511
+ R extends EntityRecordOf< K, N >,
512
+ C extends Context = DefaultContextOf< R >,
513
+ K extends Kind = KindOf< R >,
514
+ N extends Name = NameOf< R >
515
+ >(
516
+ state: State,
517
+ kind: K,
518
+ name: N,
519
+ query?: EntityQuery< C, false >
520
+ ): EntityRecordOf< K, N, C >[] | null | undefined;
521
+ }
522
+
321
523
  /**
322
524
  * Returns the Entity's records.
323
525
  *
324
- * @param {Object} state State tree
325
- * @param {string} kind Entity kind.
326
- * @param {string} name Entity name.
327
- * @param {?Object} query Optional terms query.
526
+ * @param state State tree
527
+ * @param kind Entity kind.
528
+ * @param name Entity name.
529
+ * @param query Optional terms query.
328
530
  *
329
- * @return {?Array} Records.
531
+ * @return Records.
330
532
  */
331
- export function getEntityRecords( state, kind, name, query ) {
533
+ export const getEntityRecords: GetEntityRecords = <
534
+ R extends EntityRecordOf< K, N >,
535
+ C extends Context = DefaultContextOf< R >,
536
+ K extends Kind = KindOf< R >,
537
+ N extends Name = NameOf< R >
538
+ >(
539
+ state: State,
540
+ kind: K,
541
+ name: N,
542
+ query
543
+ ) => {
332
544
  // Queried data state is prepopulated for all known entities. If this is not
333
545
  // assigned for the given parameters, then it is known to not exist.
334
546
  const queriedState = get( state.entities.records, [
@@ -340,58 +552,85 @@ export function getEntityRecords( state, kind, name, query ) {
340
552
  return null;
341
553
  }
342
554
  return getQueriedItems( queriedState, query );
343
- }
555
+ };
344
556
 
557
+ type DirtyEntityRecord = {
558
+ title: string;
559
+ key: GenericRecordKey;
560
+ name: Name;
561
+ kind: Kind;
562
+ };
345
563
  /**
346
564
  * Returns the list of dirty entity records.
347
565
  *
348
- * @param {Object} state State tree.
566
+ * @param state State tree.
349
567
  *
350
- * @return {[{ title: string, key: string, name: string, kind: string }]} The list of updated records
568
+ * @return The list of updated records
351
569
  */
352
570
  export const __experimentalGetDirtyEntityRecords = createSelector(
353
- ( state ) => {
571
+ ( state: State ): Array< DirtyEntityRecord > => {
354
572
  const {
355
573
  entities: { records },
356
574
  } = state;
357
- const dirtyRecords = [];
358
- Object.keys( records ).forEach( ( kind ) => {
359
- Object.keys( records[ kind ] ).forEach( ( name ) => {
360
- const primaryKeys = Object.keys(
361
- records[ kind ][ name ].edits
362
- ).filter(
363
- ( primaryKey ) =>
364
- // The entity record must exist (not be deleted),
365
- // and it must have edits.
366
- getEntityRecord( state, kind, name, primaryKey ) &&
367
- hasEditsForEntityRecord( state, kind, name, primaryKey )
368
- );
369
-
370
- if ( primaryKeys.length ) {
371
- const entityConfig = getEntityConfig( state, kind, name );
372
- primaryKeys.forEach( ( primaryKey ) => {
373
- const entityRecord = getEditedEntityRecord(
374
- state,
375
- kind,
376
- name,
377
- primaryKey
575
+ const dirtyRecords: DirtyEntityRecord[] = [];
576
+ ( Object.keys( records ) as Kind[] ).forEach(
577
+ < K extends Kind >( kind: K ) => {
578
+ ( Object.keys( records[ kind ] ) as Name[] ).forEach(
579
+ < N extends Name >( name: N ) => {
580
+ const primaryKeys = (
581
+ Object.keys(
582
+ records[ kind ][ name ].edits
583
+ ) as KeyOf< K, N >[]
584
+ ).filter(
585
+ ( primaryKey ) =>
586
+ // The entity record must exist (not be deleted),
587
+ // and it must have edits.
588
+ getEntityRecord(
589
+ state,
590
+ kind,
591
+ name,
592
+ primaryKey
593
+ ) &&
594
+ hasEditsForEntityRecord(
595
+ state,
596
+ kind,
597
+ name,
598
+ primaryKey
599
+ )
378
600
  );
379
- dirtyRecords.push( {
380
- // We avoid using primaryKey because it's transformed into a string
381
- // when it's used as an object key.
382
- key:
383
- entityRecord[
384
- entityConfig.key || DEFAULT_ENTITY_KEY
385
- ],
386
- title:
387
- entityConfig?.getTitle?.( entityRecord ) || '',
388
- name,
389
- kind,
390
- } );
391
- } );
392
- }
393
- } );
394
- } );
601
+
602
+ if ( primaryKeys.length ) {
603
+ const entityConfig = getEntityConfig(
604
+ state,
605
+ kind,
606
+ name
607
+ );
608
+ primaryKeys.forEach( ( primaryKey ) => {
609
+ const entityRecord = getEditedEntityRecord(
610
+ state,
611
+ kind,
612
+ name,
613
+ primaryKey
614
+ );
615
+ dirtyRecords.push( {
616
+ // We avoid using primaryKey because it's transformed into a string
617
+ // when it's used as an object key.
618
+ key: entityRecord[
619
+ entityConfig.key || DEFAULT_ENTITY_KEY
620
+ ],
621
+ title:
622
+ entityConfig?.getTitle?.(
623
+ entityRecord
624
+ ) || '',
625
+ name,
626
+ kind,
627
+ } );
628
+ } );
629
+ }
630
+ }
631
+ );
632
+ }
633
+ );
395
634
 
396
635
  return dirtyRecords;
397
636
  },
@@ -401,49 +640,65 @@ export const __experimentalGetDirtyEntityRecords = createSelector(
401
640
  /**
402
641
  * Returns the list of entities currently being saved.
403
642
  *
404
- * @param {Object} state State tree.
643
+ * @param state State tree.
405
644
  *
406
- * @return {[{ title: string, key: string, name: string, kind: string }]} The list of records being saved.
645
+ * @return The list of records being saved.
407
646
  */
408
647
  export const __experimentalGetEntitiesBeingSaved = createSelector(
409
- ( state ) => {
648
+ ( state: State ): Array< DirtyEntityRecord > => {
410
649
  const {
411
650
  entities: { records },
412
651
  } = state;
413
- const recordsBeingSaved = [];
414
- Object.keys( records ).forEach( ( kind ) => {
415
- Object.keys( records[ kind ] ).forEach( ( name ) => {
416
- const primaryKeys = Object.keys(
417
- records[ kind ][ name ].saving
418
- ).filter( ( primaryKey ) =>
419
- isSavingEntityRecord( state, kind, name, primaryKey )
420
- );
421
-
422
- if ( primaryKeys.length ) {
423
- const entityConfig = getEntityConfig( state, kind, name );
424
- primaryKeys.forEach( ( primaryKey ) => {
425
- const entityRecord = getEditedEntityRecord(
426
- state,
427
- kind,
428
- name,
429
- primaryKey
652
+ const recordsBeingSaved: DirtyEntityRecord[] = [];
653
+ ( Object.keys( records ) as Kind[] ).forEach(
654
+ < K extends Kind >( kind: K ) => {
655
+ ( Object.keys( records[ kind ] ) as Name[] ).forEach(
656
+ < N extends Name >( name: N ) => {
657
+ const primaryKeys = (
658
+ Object.keys(
659
+ records[ kind ][ name ].saving
660
+ ) as KeyOf< K, N >[]
661
+ ).filter( ( primaryKey ) =>
662
+ isSavingEntityRecord(
663
+ state,
664
+ kind,
665
+ name,
666
+ primaryKey
667
+ )
430
668
  );
431
- recordsBeingSaved.push( {
432
- // We avoid using primaryKey because it's transformed into a string
433
- // when it's used as an object key.
434
- key:
435
- entityRecord[
436
- entityConfig.key || DEFAULT_ENTITY_KEY
437
- ],
438
- title:
439
- entityConfig?.getTitle?.( entityRecord ) || '',
440
- name,
441
- kind,
442
- } );
443
- } );
444
- }
445
- } );
446
- } );
669
+
670
+ if ( primaryKeys.length ) {
671
+ const entityConfig = getEntityConfig(
672
+ state,
673
+ kind,
674
+ name
675
+ );
676
+ primaryKeys.forEach( ( primaryKey ) => {
677
+ const entityRecord = getEditedEntityRecord(
678
+ state,
679
+ kind,
680
+ name,
681
+ primaryKey
682
+ );
683
+ recordsBeingSaved.push( {
684
+ // We avoid using primaryKey because it's transformed into a string
685
+ // when it's used as an object key.
686
+ key: entityRecord[
687
+ entityConfig.key || DEFAULT_ENTITY_KEY
688
+ ],
689
+ title:
690
+ entityConfig?.getTitle?.(
691
+ entityRecord
692
+ ) || '',
693
+ name,
694
+ kind,
695
+ } );
696
+ } );
697
+ }
698
+ }
699
+ );
700
+ }
701
+ );
447
702
  return recordsBeingSaved;
448
703
  },
449
704
  ( state ) => [ state.entities.records ]
@@ -452,15 +707,25 @@ export const __experimentalGetEntitiesBeingSaved = createSelector(
452
707
  /**
453
708
  * Returns the specified entity record's edits.
454
709
  *
455
- * @param {Object} state State tree.
456
- * @param {string} kind Entity kind.
457
- * @param {string} name Entity name.
458
- * @param {number} recordId Record ID.
710
+ * @param state State tree.
711
+ * @param kind Entity kind.
712
+ * @param name Entity name.
713
+ * @param recordId Record ID.
459
714
  *
460
- * @return {Object?} The entity record's edits.
715
+ * @return The entity record's edits.
461
716
  */
462
- export function getEntityRecordEdits( state, kind, name, recordId ) {
463
- return get( state.entities.records, [ kind, name, 'edits', recordId ] );
717
+ export function getEntityRecordEdits< K extends Kind, N extends Name >(
718
+ state: State,
719
+ kind: K,
720
+ name: N,
721
+ recordId: KeyOf< K, N >
722
+ ): Optional< any > {
723
+ return get( state.entities.records, [
724
+ kind,
725
+ name,
726
+ 'edits',
727
+ recordId as string | number,
728
+ ] );
464
729
  }
465
730
 
466
731
  /**
@@ -470,15 +735,20 @@ export function getEntityRecordEdits( state, kind, name, recordId ) {
470
735
  * are not considered for change detection.
471
736
  * They are defined in the entity's config.
472
737
  *
473
- * @param {Object} state State tree.
474
- * @param {string} kind Entity kind.
475
- * @param {string} name Entity name.
476
- * @param {number} recordId Record ID.
738
+ * @param state State tree.
739
+ * @param kind Entity kind.
740
+ * @param name Entity name.
741
+ * @param recordId Record ID.
477
742
  *
478
- * @return {Object?} The entity record's non transient edits.
743
+ * @return The entity record's non transient edits.
479
744
  */
480
745
  export const getEntityRecordNonTransientEdits = createSelector(
481
- ( state, kind, name, recordId ) => {
746
+ < K extends Kind, N extends Name >(
747
+ state: State,
748
+ kind: K,
749
+ name: N,
750
+ recordId: KeyOf< K, N >
751
+ ): Optional< any > => {
482
752
  const { transientEdits } = getEntityConfig( state, kind, name ) || {};
483
753
  const edits = getEntityRecordEdits( state, kind, name, recordId ) || {};
484
754
  if ( ! transientEdits ) {
@@ -491,7 +761,7 @@ export const getEntityRecordNonTransientEdits = createSelector(
491
761
  return acc;
492
762
  }, {} );
493
763
  },
494
- ( state, kind, name, recordId ) => [
764
+ ( state: State, kind: Kind, name: Name, recordId: GenericRecordKey ) => [
495
765
  state.entities.config,
496
766
  get( state.entities.records, [ kind, name, 'edits', recordId ] ),
497
767
  ]
@@ -501,14 +771,19 @@ export const getEntityRecordNonTransientEdits = createSelector(
501
771
  * Returns true if the specified entity record has edits,
502
772
  * and false otherwise.
503
773
  *
504
- * @param {Object} state State tree.
505
- * @param {string} kind Entity kind.
506
- * @param {string} name Entity name.
507
- * @param {number|string} recordId Record ID.
774
+ * @param state State tree.
775
+ * @param kind Entity kind.
776
+ * @param name Entity name.
777
+ * @param recordId Record ID.
508
778
  *
509
- * @return {boolean} Whether the entity record has edits or not.
779
+ * @return Whether the entity record has edits or not.
510
780
  */
511
- export function hasEditsForEntityRecord( state, kind, name, recordId ) {
781
+ export function hasEditsForEntityRecord< K extends Kind, N extends Name >(
782
+ state: State,
783
+ kind: K,
784
+ name: N,
785
+ recordId: KeyOf< K, N >
786
+ ): boolean {
512
787
  return (
513
788
  isSavingEntityRecord( state, kind, name, recordId ) ||
514
789
  Object.keys(
@@ -520,19 +795,30 @@ export function hasEditsForEntityRecord( state, kind, name, recordId ) {
520
795
  /**
521
796
  * Returns the specified entity record, merged with its edits.
522
797
  *
523
- * @param {Object} state State tree.
524
- * @param {string} kind Entity kind.
525
- * @param {string} name Entity name.
526
- * @param {number|string} recordId Record ID.
798
+ * @param state State tree.
799
+ * @param kind Entity kind.
800
+ * @param name Entity name.
801
+ * @param recordId Record ID.
527
802
  *
528
- * @return {Object?} The entity record, merged with its edits.
803
+ * @return The entity record, merged with its edits.
529
804
  */
530
805
  export const getEditedEntityRecord = createSelector(
531
- ( state, kind, name, recordId ) => ( {
806
+ < K extends Kind, N extends Name >(
807
+ state: State,
808
+ kind: K,
809
+ name: N,
810
+ recordId: KeyOf< K, N >
811
+ ): EntityRecord | undefined => ( {
532
812
  ...getRawEntityRecord( state, kind, name, recordId ),
533
813
  ...getEntityRecordEdits( state, kind, name, recordId ),
534
814
  } ),
535
- ( state, kind, name, recordId, query ) => {
815
+ (
816
+ state: State,
817
+ kind: Kind,
818
+ name: Name,
819
+ recordId: GenericRecordKey,
820
+ query?: EntityQuery< any >
821
+ ) => {
536
822
  const context = query?.context ?? 'default';
537
823
  return [
538
824
  state.entities.config,
@@ -560,14 +846,19 @@ export const getEditedEntityRecord = createSelector(
560
846
  /**
561
847
  * Returns true if the specified entity record is autosaving, and false otherwise.
562
848
  *
563
- * @param {Object} state State tree.
564
- * @param {string} kind Entity kind.
565
- * @param {string} name Entity name.
566
- * @param {number} recordId Record ID.
849
+ * @param state State tree.
850
+ * @param kind Entity kind.
851
+ * @param name Entity name.
852
+ * @param recordId Record ID.
567
853
  *
568
- * @return {boolean} Whether the entity record is autosaving or not.
854
+ * @return Whether the entity record is autosaving or not.
569
855
  */
570
- export function isAutosavingEntityRecord( state, kind, name, recordId ) {
856
+ export function isAutosavingEntityRecord(
857
+ state: State,
858
+ kind: Kind,
859
+ name: Name,
860
+ recordId: GenericRecordKey
861
+ ): boolean {
571
862
  const { pending, isAutosave } = get(
572
863
  state.entities.records,
573
864
  [ kind, name, 'saving', recordId ],
@@ -579,17 +870,22 @@ export function isAutosavingEntityRecord( state, kind, name, recordId ) {
579
870
  /**
580
871
  * Returns true if the specified entity record is saving, and false otherwise.
581
872
  *
582
- * @param {Object} state State tree.
583
- * @param {string} kind Entity kind.
584
- * @param {string} name Entity name.
585
- * @param {number|string} recordId Record ID.
873
+ * @param state State tree.
874
+ * @param kind Entity kind.
875
+ * @param name Entity name.
876
+ * @param recordId Record ID.
586
877
  *
587
- * @return {boolean} Whether the entity record is saving or not.
878
+ * @return Whether the entity record is saving or not.
588
879
  */
589
- export function isSavingEntityRecord( state, kind, name, recordId ) {
880
+ export function isSavingEntityRecord< K extends Kind, N extends Name >(
881
+ state: State,
882
+ kind: K,
883
+ name: N,
884
+ recordId: KeyOf< K, N >
885
+ ): boolean {
590
886
  return get(
591
887
  state.entities.records,
592
- [ kind, name, 'saving', recordId, 'pending' ],
888
+ [ kind, name, 'saving', recordId as GenericRecordKey, 'pending' ],
593
889
  false
594
890
  );
595
891
  }
@@ -597,14 +893,19 @@ export function isSavingEntityRecord( state, kind, name, recordId ) {
597
893
  /**
598
894
  * Returns true if the specified entity record is deleting, and false otherwise.
599
895
  *
600
- * @param {Object} state State tree.
601
- * @param {string} kind Entity kind.
602
- * @param {string} name Entity name.
603
- * @param {number} recordId Record ID.
896
+ * @param state State tree.
897
+ * @param kind Entity kind.
898
+ * @param name Entity name.
899
+ * @param recordId Record ID.
604
900
  *
605
- * @return {boolean} Whether the entity record is deleting or not.
901
+ * @return Whether the entity record is deleting or not.
606
902
  */
607
- export function isDeletingEntityRecord( state, kind, name, recordId ) {
903
+ export function isDeletingEntityRecord(
904
+ state: State,
905
+ kind: Kind,
906
+ name: Name,
907
+ recordId: GenericRecordKey
908
+ ): boolean {
608
909
  return get(
609
910
  state.entities.records,
610
911
  [ kind, name, 'deleting', recordId, 'pending' ],
@@ -615,14 +916,19 @@ export function isDeletingEntityRecord( state, kind, name, recordId ) {
615
916
  /**
616
917
  * Returns the specified entity record's last save error.
617
918
  *
618
- * @param {Object} state State tree.
619
- * @param {string} kind Entity kind.
620
- * @param {string} name Entity name.
621
- * @param {number} recordId Record ID.
919
+ * @param state State tree.
920
+ * @param kind Entity kind.
921
+ * @param name Entity name.
922
+ * @param recordId Record ID.
622
923
  *
623
- * @return {Object?} The entity record's save error.
924
+ * @return The entity record's save error.
624
925
  */
625
- export function getLastEntitySaveError( state, kind, name, recordId ) {
926
+ export function getLastEntitySaveError(
927
+ state: State,
928
+ kind: Kind,
929
+ name: Name,
930
+ recordId: GenericRecordKey
931
+ ): any {
626
932
  return get( state.entities.records, [
627
933
  kind,
628
934
  name,
@@ -635,14 +941,19 @@ export function getLastEntitySaveError( state, kind, name, recordId ) {
635
941
  /**
636
942
  * Returns the specified entity record's last delete error.
637
943
  *
638
- * @param {Object} state State tree.
639
- * @param {string} kind Entity kind.
640
- * @param {string} name Entity name.
641
- * @param {number} recordId Record ID.
944
+ * @param state State tree.
945
+ * @param kind Entity kind.
946
+ * @param name Entity name.
947
+ * @param recordId Record ID.
642
948
  *
643
- * @return {Object?} The entity record's save error.
949
+ * @return The entity record's save error.
644
950
  */
645
- export function getLastEntityDeleteError( state, kind, name, recordId ) {
951
+ export function getLastEntityDeleteError(
952
+ state: State,
953
+ kind: Kind,
954
+ name: Name,
955
+ recordId: GenericRecordKey
956
+ ): any {
646
957
  return get( state.entities.records, [
647
958
  kind,
648
959
  name,
@@ -659,11 +970,11 @@ export function getLastEntityDeleteError( state, kind, name, recordId ) {
659
970
  * of the history stack we are at. 0 is the
660
971
  * last edit, -1 is the second last, and so on.
661
972
  *
662
- * @param {Object} state State tree.
973
+ * @param state State tree.
663
974
  *
664
- * @return {number} The current undo offset.
975
+ * @return The current undo offset.
665
976
  */
666
- function getCurrentUndoOffset( state ) {
977
+ function getCurrentUndoOffset( state: State ): number {
667
978
  return state.undo.offset;
668
979
  }
669
980
 
@@ -671,11 +982,11 @@ function getCurrentUndoOffset( state ) {
671
982
  * Returns the previous edit from the current undo offset
672
983
  * for the entity records edits history, if any.
673
984
  *
674
- * @param {Object} state State tree.
985
+ * @param state State tree.
675
986
  *
676
- * @return {Object?} The edit.
987
+ * @return The edit.
677
988
  */
678
- export function getUndoEdit( state ) {
989
+ export function getUndoEdit( state: State ): Optional< any > {
679
990
  return state.undo[ state.undo.length - 2 + getCurrentUndoOffset( state ) ];
680
991
  }
681
992
 
@@ -683,11 +994,11 @@ export function getUndoEdit( state ) {
683
994
  * Returns the next edit from the current undo offset
684
995
  * for the entity records edits history, if any.
685
996
  *
686
- * @param {Object} state State tree.
997
+ * @param state State tree.
687
998
  *
688
- * @return {Object?} The edit.
999
+ * @return The edit.
689
1000
  */
690
- export function getRedoEdit( state ) {
1001
+ export function getRedoEdit( state: State ): Optional< any > {
691
1002
  return state.undo[ state.undo.length + getCurrentUndoOffset( state ) ];
692
1003
  }
693
1004
 
@@ -695,11 +1006,11 @@ export function getRedoEdit( state ) {
695
1006
  * Returns true if there is a previous edit from the current undo offset
696
1007
  * for the entity records edits history, and false otherwise.
697
1008
  *
698
- * @param {Object} state State tree.
1009
+ * @param state State tree.
699
1010
  *
700
- * @return {boolean} Whether there is a previous edit or not.
1011
+ * @return Whether there is a previous edit or not.
701
1012
  */
702
- export function hasUndo( state ) {
1013
+ export function hasUndo( state: State ): boolean {
703
1014
  return Boolean( getUndoEdit( state ) );
704
1015
  }
705
1016
 
@@ -707,56 +1018,56 @@ export function hasUndo( state ) {
707
1018
  * Returns true if there is a next edit from the current undo offset
708
1019
  * for the entity records edits history, and false otherwise.
709
1020
  *
710
- * @param {Object} state State tree.
1021
+ * @param state State tree.
711
1022
  *
712
- * @return {boolean} Whether there is a next edit or not.
1023
+ * @return Whether there is a next edit or not.
713
1024
  */
714
- export function hasRedo( state ) {
1025
+ export function hasRedo( state: State ): boolean {
715
1026
  return Boolean( getRedoEdit( state ) );
716
1027
  }
717
1028
 
718
1029
  /**
719
1030
  * Return the current theme.
720
1031
  *
721
- * @param {Object} state Data state.
1032
+ * @param state Data state.
722
1033
  *
723
- * @return {Object} The current theme.
1034
+ * @return The current theme.
724
1035
  */
725
- export function getCurrentTheme( state ) {
1036
+ export function getCurrentTheme( state: State ): any {
726
1037
  return getEntityRecord( state, 'root', 'theme', state.currentTheme );
727
1038
  }
728
1039
 
729
1040
  /**
730
1041
  * Return the ID of the current global styles object.
731
1042
  *
732
- * @param {Object} state Data state.
1043
+ * @param state Data state.
733
1044
  *
734
- * @return {string} The current global styles ID.
1045
+ * @return The current global styles ID.
735
1046
  */
736
- export function __experimentalGetCurrentGlobalStylesId( state ) {
1047
+ export function __experimentalGetCurrentGlobalStylesId( state: State ): string {
737
1048
  return state.currentGlobalStylesId;
738
1049
  }
739
1050
 
740
1051
  /**
741
1052
  * Return theme supports data in the index.
742
1053
  *
743
- * @param {Object} state Data state.
1054
+ * @param state Data state.
744
1055
  *
745
- * @return {*} Index data.
1056
+ * @return Index data.
746
1057
  */
747
- export function getThemeSupports( state ) {
1058
+ export function getThemeSupports( state: State ): any {
748
1059
  return getCurrentTheme( state )?.theme_supports ?? EMPTY_OBJECT;
749
1060
  }
750
1061
 
751
1062
  /**
752
1063
  * Returns the embed preview for the given URL.
753
1064
  *
754
- * @param {Object} state Data state.
755
- * @param {string} url Embedded URL.
1065
+ * @param state Data state.
1066
+ * @param url Embedded URL.
756
1067
  *
757
- * @return {*} Undefined if the preview has not been fetched, otherwise, the preview fetched from the embed preview API.
1068
+ * @return Undefined if the preview has not been fetched, otherwise, the preview fetched from the embed preview API.
758
1069
  */
759
- export function getEmbedPreview( state, url ) {
1070
+ export function getEmbedPreview( state: State, url: string ): any {
760
1071
  return state.embedPreviews[ url ];
761
1072
  }
762
1073
 
@@ -767,12 +1078,12 @@ export function getEmbedPreview( state, url ) {
767
1078
  * We need to be able to determine if a URL is embeddable or not, based on what we
768
1079
  * get back from the oEmbed preview API.
769
1080
  *
770
- * @param {Object} state Data state.
771
- * @param {string} url Embedded URL.
1081
+ * @param state Data state.
1082
+ * @param url Embedded URL.
772
1083
  *
773
- * @return {boolean} Is the preview for the URL an oEmbed link fallback.
1084
+ * @return Is the preview for the URL an oEmbed link fallback.
774
1085
  */
775
- export function isPreviewEmbedFallback( state, url ) {
1086
+ export function isPreviewEmbedFallback( state: State, url: string ): boolean {
776
1087
  const preview = state.embedPreviews[ url ];
777
1088
  const oEmbedLinkCheck = '<a href="' + url + '">' + url + '</a>';
778
1089
  if ( ! preview ) {
@@ -790,15 +1101,20 @@ export function isPreviewEmbedFallback( state, url ) {
790
1101
  *
791
1102
  * https://developer.wordpress.org/rest-api/reference/
792
1103
  *
793
- * @param {Object} state Data state.
794
- * @param {string} action Action to check. One of: 'create', 'read', 'update', 'delete'.
795
- * @param {string} resource REST resource to check, e.g. 'media' or 'posts'.
796
- * @param {string=} id Optional ID of the rest resource to check.
1104
+ * @param state Data state.
1105
+ * @param action Action to check. One of: 'create', 'read', 'update', 'delete'.
1106
+ * @param resource REST resource to check, e.g. 'media' or 'posts'.
1107
+ * @param id Optional ID of the rest resource to check.
797
1108
  *
798
- * @return {boolean|undefined} Whether or not the user can perform the action,
1109
+ * @return Whether or not the user can perform the action,
799
1110
  * or `undefined` if the OPTIONS request is still being made.
800
1111
  */
801
- export function canUser( state, action, resource, id ) {
1112
+ export function canUser(
1113
+ state: State,
1114
+ action: string,
1115
+ resource: string,
1116
+ id?: GenericRecordKey
1117
+ ): boolean | undefined {
802
1118
  const key = compact( [ action, resource, id ] ).join( '/' );
803
1119
  return get( state, [ 'userPermissions', key ] );
804
1120
  }
@@ -811,14 +1127,19 @@ export function canUser( state, action, resource, id ) {
811
1127
  *
812
1128
  * https://developer.wordpress.org/rest-api/reference/
813
1129
  *
814
- * @param {Object} state Data state.
815
- * @param {string} kind Entity kind.
816
- * @param {string} name Entity name.
817
- * @param {string} recordId Record's id.
818
- * @return {boolean|undefined} Whether or not the user can edit,
1130
+ * @param state Data state.
1131
+ * @param kind Entity kind.
1132
+ * @param name Entity name.
1133
+ * @param recordId Record's id.
1134
+ * @return Whether or not the user can edit,
819
1135
  * or `undefined` if the OPTIONS request is still being made.
820
1136
  */
821
- export function canUserEditEntityRecord( state, kind, name, recordId ) {
1137
+ export function canUserEditEntityRecord(
1138
+ state: State,
1139
+ kind: Kind,
1140
+ name: Name,
1141
+ recordId: GenericRecordKey
1142
+ ): boolean | undefined {
822
1143
  const entityConfig = getEntityConfig( state, kind, name );
823
1144
  if ( ! entityConfig ) {
824
1145
  return false;
@@ -834,27 +1155,36 @@ export function canUserEditEntityRecord( state, kind, name, recordId ) {
834
1155
  * May return multiple autosaves since the backend stores one autosave per
835
1156
  * author for each post.
836
1157
  *
837
- * @param {Object} state State tree.
838
- * @param {string} postType The type of the parent post.
839
- * @param {number} postId The id of the parent post.
1158
+ * @param state State tree.
1159
+ * @param postType The type of the parent post.
1160
+ * @param postId The id of the parent post.
840
1161
  *
841
- * @return {?Array} An array of autosaves for the post, or undefined if there is none.
1162
+ * @return An array of autosaves for the post, or undefined if there is none.
842
1163
  */
843
- export function getAutosaves( state, postType, postId ) {
1164
+ export function getAutosaves(
1165
+ state: State,
1166
+ postType: string,
1167
+ postId: GenericRecordKey
1168
+ ): Array< any > | undefined {
844
1169
  return state.autosaves[ postId ];
845
1170
  }
846
1171
 
847
1172
  /**
848
1173
  * Returns the autosave for the post and author.
849
1174
  *
850
- * @param {Object} state State tree.
851
- * @param {string} postType The type of the parent post.
852
- * @param {number} postId The id of the parent post.
853
- * @param {number} authorId The id of the author.
1175
+ * @param state State tree.
1176
+ * @param postType The type of the parent post.
1177
+ * @param postId The id of the parent post.
1178
+ * @param authorId The id of the author.
854
1179
  *
855
- * @return {?Object} The autosave for the post and author.
1180
+ * @return The autosave for the post and author.
856
1181
  */
857
- export function getAutosave( state, postType, postId, authorId ) {
1182
+ export function getAutosave(
1183
+ state: State,
1184
+ postType: string,
1185
+ postId: GenericRecordKey,
1186
+ authorId: GenericRecordKey
1187
+ ): EntityRecord | undefined {
858
1188
  if ( authorId === undefined ) {
859
1189
  return;
860
1190
  }
@@ -866,19 +1196,24 @@ export function getAutosave( state, postType, postId, authorId ) {
866
1196
  /**
867
1197
  * Returns true if the REST request for autosaves has completed.
868
1198
  *
869
- * @param {Object} state State tree.
870
- * @param {string} postType The type of the parent post.
871
- * @param {number} postId The id of the parent post.
1199
+ * @param state State tree.
1200
+ * @param postType The type of the parent post.
1201
+ * @param postId The id of the parent post.
872
1202
  *
873
- * @return {boolean} True if the REST request was completed. False otherwise.
1203
+ * @return True if the REST request was completed. False otherwise.
874
1204
  */
875
1205
  export const hasFetchedAutosaves = createRegistrySelector(
876
- ( select ) => ( state, postType, postId ) => {
877
- return select( STORE_NAME ).hasFinishedResolution( 'getAutosaves', [
878
- postType,
879
- postId,
880
- ] );
881
- }
1206
+ ( select ) =>
1207
+ (
1208
+ state: State,
1209
+ postType: string,
1210
+ postId: GenericRecordKey
1211
+ ): boolean => {
1212
+ return select( STORE_NAME ).hasFinishedResolution( 'getAutosaves', [
1213
+ postType,
1214
+ postId,
1215
+ ] );
1216
+ }
882
1217
  );
883
1218
 
884
1219
  /**
@@ -895,13 +1230,14 @@ export const hasFetchedAutosaves = createRegistrySelector(
895
1230
  * );
896
1231
  * ```
897
1232
  *
898
- * @param {Object} state Editor state.
1233
+ * @param state Editor state.
899
1234
  *
900
- * @return {*} A value whose reference will change only when an edit occurs.
1235
+ * @return A value whose reference will change only when an edit occurs.
901
1236
  */
902
1237
  export const getReferenceByDistinctEdits = createSelector(
903
- () => [],
904
- ( state ) => [
1238
+ // This unused state argument is listed here for the documentation generating tool (docgen).
1239
+ ( state: State ) => [],
1240
+ ( state: State ) => [
905
1241
  state.undo.length,
906
1242
  state.undo.offset,
907
1243
  state.undo.flattenedUndo,
@@ -911,12 +1247,15 @@ export const getReferenceByDistinctEdits = createSelector(
911
1247
  /**
912
1248
  * Retrieve the frontend template used for a given link.
913
1249
  *
914
- * @param {Object} state Editor state.
915
- * @param {string} link Link.
1250
+ * @param state Editor state.
1251
+ * @param link Link.
916
1252
  *
917
- * @return {Object?} The template record.
1253
+ * @return The template record.
918
1254
  */
919
- export function __experimentalGetTemplateForLink( state, link ) {
1255
+ export function __experimentalGetTemplateForLink(
1256
+ state: State,
1257
+ link: string
1258
+ ): WpTemplate< 'edit' > | null {
920
1259
  const records = getEntityRecords( state, 'postType', 'wp_template', {
921
1260
  'find-template': link,
922
1261
  } );
@@ -936,11 +1275,13 @@ export function __experimentalGetTemplateForLink( state, link ) {
936
1275
  /**
937
1276
  * Retrieve the current theme's base global styles
938
1277
  *
939
- * @param {Object} state Editor state.
1278
+ * @param state Editor state.
940
1279
  *
941
- * @return {Object|null} The Global Styles object.
1280
+ * @return The Global Styles object.
942
1281
  */
943
- export function __experimentalGetCurrentThemeBaseGlobalStyles( state ) {
1282
+ export function __experimentalGetCurrentThemeBaseGlobalStyles(
1283
+ state: State
1284
+ ): any {
944
1285
  const currentTheme = getCurrentTheme( state );
945
1286
  if ( ! currentTheme ) {
946
1287
  return null;
@@ -951,11 +1292,13 @@ export function __experimentalGetCurrentThemeBaseGlobalStyles( state ) {
951
1292
  /**
952
1293
  * Return the ID of the current global styles object.
953
1294
  *
954
- * @param {Object} state Data state.
1295
+ * @param state Data state.
955
1296
  *
956
- * @return {string|null} The current global styles ID.
1297
+ * @return The current global styles ID.
957
1298
  */
958
- export function __experimentalGetCurrentThemeGlobalStylesVariations( state ) {
1299
+ export function __experimentalGetCurrentThemeGlobalStylesVariations(
1300
+ state: State
1301
+ ): string | null {
959
1302
  const currentTheme = getCurrentTheme( state );
960
1303
  if ( ! currentTheme ) {
961
1304
  return null;
@@ -966,21 +1309,21 @@ export function __experimentalGetCurrentThemeGlobalStylesVariations( state ) {
966
1309
  /**
967
1310
  * Retrieve the list of registered block patterns.
968
1311
  *
969
- * @param {Object} state Data state.
1312
+ * @param state Data state.
970
1313
  *
971
- * @return {Array} Block pattern list.
1314
+ * @return Block pattern list.
972
1315
  */
973
- export function getBlockPatterns( state ) {
1316
+ export function getBlockPatterns( state: State ): Array< any > {
974
1317
  return state.blockPatterns;
975
1318
  }
976
1319
 
977
1320
  /**
978
1321
  * Retrieve the list of registered block pattern categories.
979
1322
  *
980
- * @param {Object} state Data state.
1323
+ * @param state Data state.
981
1324
  *
982
- * @return {Array} Block pattern category list.
1325
+ * @return Block pattern category list.
983
1326
  */
984
- export function getBlockPatternCategories( state ) {
1327
+ export function getBlockPatternCategories( state: State ): Array< any > {
985
1328
  return state.blockPatternCategories;
986
1329
  }