@wordpress/core-data 7.0.1 → 7.1.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 7.1.0 (2024-06-15)
6
+
5
7
  ## 7.0.0 (2024-05-31)
6
8
 
7
9
  ### Breaking Changes
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["@wordpress/core-data/src/entity-types/helpers.ts"],"sourcesContent":["/**\n * Internal dependencies\n */\nimport type { EntityRecord } from './index';\n\nexport interface AvatarUrls {\n\t/**\n\t * Avatar URL with image size of 24 pixels.\n\t */\n\t'24': string;\n\t/**\n\t * Avatar URL with image size of 48 pixels.\n\t */\n\t'48': string;\n\t/**\n\t * Avatar URL with image size of 96 pixels.\n\t */\n\t'96': string;\n}\n\nexport type MediaType = 'image' | 'file';\nexport type CommentingStatus = 'open' | 'closed';\nexport type PingStatus = 'open' | 'closed';\nexport type PostStatus = 'publish' | 'future' | 'draft' | 'pending' | 'private';\nexport type PostFormat =\n\t| 'standard'\n\t| 'aside'\n\t| 'chat'\n\t| 'gallery'\n\t| 'link'\n\t| 'image'\n\t| 'quote'\n\t| 'status'\n\t| 'video'\n\t| 'audio';\n\n/**\n * The REST API context parameter.\n */\nexport type Context = 'view' | 'edit' | 'embed';\n\n/**\n * ContextualField makes the field available only in the specified given contexts,\n * and ensure the field is absent from the object when in a different context.\n *\n * @example\n * ```ts\n * interface Post< C extends Context > {\n * \t…\n * \tmodified: ContextualField< string, 'edit' | 'view', C >;\n * \tpassword: ContextualField< string, 'edit', C >;\n * \t…\n * }\n *\n * const post: Post<'edit'> = …\n * // post.modified exists as a string\n * // post.password exists as a string\n *\n * const post: Post<'view'> = …\n * // post.modified still exists as a string\n * // post.password is missing, undefined, because we're not in the `edit` context.\n * ```\n */\nexport type ContextualField<\n\tFieldType,\n\tAvailableInContexts extends Context,\n\tC extends Context,\n> = AvailableInContexts extends C ? FieldType : never;\n\n/**\n * Removes all the properties of type never, even the deeply nested ones.\n *\n * @example\n * ```ts\n * type MyType = {\n * foo: string;\n * bar: never;\n * nested: {\n * foo: string;\n * bar: never;\n * }\n * }\n * const x = {} as OmitNevers<MyType>;\n * // x is of type { foo: string; nested: { foo: string; }}\n * // The `never` properties were removed entirely\n * ```\n */\nexport type OmitNevers<\n\tT,\n\tNevers = {\n\t\t[ K in keyof T ]: Exclude< T[ K ], undefined > extends never\n\t\t\t? never\n\t\t\t: T[ K ] extends Record< string, unknown >\n\t\t\t? OmitNevers< T[ K ] >\n\t\t\t: T[ K ];\n\t},\n> = Pick<\n\tNevers,\n\t{\n\t\t[ K in keyof Nevers ]: Nevers[ K ] extends never ? never : K;\n\t}[ keyof Nevers ]\n>;\n\n/**\n * A string that the server renders which often involves\n * modifications from the raw source string.\n *\n * For example, block HTML with the comment delimiters exists\n * in `post_content` but those comments are stripped out when\n * rendering to a page view. Similarly, plugins might modify\n * content or replace shortcodes.\n */\nexport interface RenderedText< C extends Context > {\n\t/**\n\t * The source string which will be rendered on page views.\n\t */\n\traw: ContextualField< string, 'edit', C >;\n\t/**\n\t * The output of the raw source after processing and filtering on the server.\n\t */\n\trendered: string;\n}\n\n/**\n * Updatable<EntityRecord> is a type describing Edited Entity Records. They are like\n * regular Entity Records, but they have all the local edits applied on top of the REST API data.\n *\n * This turns certain field from an object into a string.\n *\n * Entities like Post have fields that only be rendered on the server, like title, excerpt,\n * and content. The REST API exposes both the raw markup and the rendered version of those fields.\n * For example, in the block editor, content.rendered could used as a visual preview, and\n * content.raw could be used to populate the code editor.\n *\n * When updating these rendered fields, Javascript is not be able to properly render arbitrary block\n * markup. Therefore, it stores only the raw markup without the rendered part. And since that's a string,\n * the entire field becomes a string.\n *\n * @example\n * ```ts\n * type Post< C extends Context > {\n * title: RenderedText< C >;\n * }\n * const post = {} as Post;\n * // post.title is an object with raw and rendered properties\n *\n * const updatablePost = {} as Updatable< Post >;\n * // updatablePost.title is a string\n * ```\n */\nexport type Updatable< T extends EntityRecord< 'edit' > > = {\n\t[ K in keyof T ]: T[ K ] extends RenderedText< any > ? string : T[ K ];\n};\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["@wordpress/core-data/src/entity-types/helpers.ts"],"sourcesContent":["/**\n * Internal dependencies\n */\nimport type { EntityRecord } from './index';\n\nexport interface AvatarUrls {\n\t/**\n\t * Avatar URL with image size of 24 pixels.\n\t */\n\t'24': string;\n\t/**\n\t * Avatar URL with image size of 48 pixels.\n\t */\n\t'48': string;\n\t/**\n\t * Avatar URL with image size of 96 pixels.\n\t */\n\t'96': string;\n}\n\nexport type MediaType = 'image' | 'file';\nexport type CommentingStatus = 'open' | 'closed';\nexport type PingStatus = 'open' | 'closed';\nexport type PostStatus = 'publish' | 'future' | 'draft' | 'pending' | 'private';\nexport type PostFormat =\n\t| 'standard'\n\t| 'aside'\n\t| 'chat'\n\t| 'gallery'\n\t| 'link'\n\t| 'image'\n\t| 'quote'\n\t| 'status'\n\t| 'video'\n\t| 'audio';\n\n/**\n * The REST API context parameter.\n */\nexport type Context = 'view' | 'edit' | 'embed';\n\n/**\n * ContextualField makes the field available only in the specified given contexts,\n * and ensure the field is absent from the object when in a different context.\n *\n * @example\n * ```ts\n * interface Post< C extends Context > {\n * \t…\n * \tmodified: ContextualField< string, 'edit' | 'view', C >;\n * \tpassword: ContextualField< string, 'edit', C >;\n * \t…\n * }\n *\n * const post: Post<'edit'> = …\n * // post.modified exists as a string\n * // post.password exists as a string\n *\n * const post: Post<'view'> = …\n * // post.modified still exists as a string\n * // post.password is missing, undefined, because we're not in the `edit` context.\n * ```\n */\nexport type ContextualField<\n\tFieldType,\n\tAvailableInContexts extends Context,\n\tC extends Context,\n> = AvailableInContexts extends C ? FieldType : never;\n\n/**\n * Removes all the properties of type never, even the deeply nested ones.\n *\n * @example\n * ```ts\n * type MyType = {\n * foo: string;\n * bar: never;\n * nested: {\n * foo: string;\n * bar: never;\n * }\n * }\n * const x = {} as OmitNevers<MyType>;\n * // x is of type { foo: string; nested: { foo: string; }}\n * // The `never` properties were removed entirely\n * ```\n */\nexport type OmitNevers<\n\tT,\n\tNevers = {\n\t\t[ K in keyof T ]: Exclude< T[ K ], undefined > extends never\n\t\t\t? never\n\t\t\t: T[ K ] extends Record< string, unknown >\n\t\t\t? OmitNevers< T[ K ] >\n\t\t\t: T[ K ];\n\t},\n> = Pick<\n\tNevers,\n\t{\n\t\t[ K in keyof Nevers ]: Nevers[ K ] extends never ? never : K;\n\t}[ keyof Nevers ]\n>;\n\n/**\n * A string that the server renders which often involves\n * modifications from the raw source string.\n *\n * For example, block HTML with the comment delimiters exists\n * in `post_content` but those comments are stripped out when\n * rendering to a page view. Similarly, plugins might modify\n * content or replace shortcodes.\n */\nexport interface RenderedText< C extends Context > {\n\t/**\n\t * The source string which will be rendered on page views.\n\t */\n\traw: ContextualField< string, 'edit', C >;\n\t/**\n\t * The output of the raw source after processing and filtering on the server.\n\t */\n\trendered: string;\n}\n\n/**\n * Updatable<EntityRecord> is a type describing Edited Entity Records. They are like\n * regular Entity Records, but they have all the local edits applied on top of the REST API data.\n *\n * This turns certain field from an object into a string.\n *\n * Entities like Post have fields that only be rendered on the server, like title, excerpt,\n * and content. The REST API exposes both the raw markup and the rendered version of those fields.\n * For example, in the block editor, content.rendered could used as a visual preview, and\n * content.raw could be used to populate the code editor.\n *\n * When updating these rendered fields, JavaScript is not be able to properly render arbitrary block\n * markup. Therefore, it stores only the raw markup without the rendered part. And since that's a string,\n * the entire field becomes a string.\n *\n * @example\n * ```ts\n * type Post< C extends Context > {\n * title: RenderedText< C >;\n * }\n * const post = {} as Post;\n * // post.title is an object with raw and rendered properties\n *\n * const updatablePost = {} as Updatable< Post >;\n * // updatablePost.title is a string\n * ```\n */\nexport type Updatable< T extends EntityRecord< 'edit' > > = {\n\t[ K in keyof T ]: T[ K ] extends RenderedText< any > ? string : T[ K ];\n};\n"],"mappings":"","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["@wordpress/core-data/src/entity-types/plugin.ts"],"sourcesContent":["/**\n * Internal dependencies\n */\nimport type {\n\tContext,\n\tContextualField,\n\tRenderedText,\n\tOmitNevers,\n} from './helpers';\n\nimport type { BaseEntityRecords as _BaseEntityRecords } from './base-entity-records';\n\ndeclare module './base-entity-records' {\n\texport namespace BaseEntityRecords {\n\t\texport interface Plugin< C extends Context > {\n\t\t\t/**\n\t\t\t * The plugin file.\n\t\t\t */\n\t\t\tplugin: string;\n\t\t\t/**\n\t\t\t * The plugin activation status.\n\t\t\t */\n\t\t\tstatus: PluginStatus;\n\t\t\t/**\n\t\t\t * The plugin name.\n\t\t\t */\n\t\t\tname: string;\n\t\t\t/**\n\t\t\t * The plugin's website address.\n\t\t\t */\n\t\t\tplugin_uri: ContextualField< string, 'view' | 'edit', C >;\n\t\t\t/**\n\t\t\t * The plugin author.\n\t\t\t */\n\t\t\tauthor: ContextualField<\n\t\t\t\tRecord< string, string >,\n\t\t\t\t'view' | 'edit',\n\t\t\t\tC\n\t\t\t>;\n\t\t\t/**\n\t\t\t * Plugin author's website address.\n\t\t\t */\n\t\t\tauthor_uri: ContextualField< string, 'view' | 'edit', C >;\n\t\t\t/**\n\t\t\t * The plugin description.\n\t\t\t */\n\t\t\tdescription: ContextualField<\n\t\t\t\tRenderedText< 'edit' >,\n\t\t\t\t'view' | 'edit',\n\t\t\t\tC\n\t\t\t>;\n\t\t\t/**\n\t\t\t * The plugin version number.\n\t\t\t */\n\t\t\tversion: ContextualField< string, 'view' | 'edit', C >;\n\t\t\t/**\n\t\t\t * Whether the plugin can only be activated network-wide.\n\t\t\t */\n\t\t\tnetwork_only: boolean;\n\t\t\t/**\n\t\t\t * Minimum required version of WordPress.\n\t\t\t */\n\t\t\trequires_wp: string;\n\t\t\t/**\n\t\t\t * Minimum required version of PHP.\n\t\t\t */\n\t\t\trequires_php: string;\n\t\t\t/**\n\t\t\t * The plugin's text domain.\n\t\t\t */\n\t\t\ttextdomain: ContextualField< string, 'view' | 'edit', C >;\n\t\t}\n\t}\n}\n\nexport type PluginStatus = 'active' | 'inactive';\nexport type Plugin< C extends Context = 'edit' > = OmitNevers<\n\t_BaseEntityRecords.Plugin< C >\n>;\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["@wordpress/core-data/src/entity-types/plugin.ts"],"sourcesContent":["/**\n * Internal dependencies\n */\nimport type {\n\tContext,\n\tContextualField,\n\tRenderedText,\n\tOmitNevers,\n} from './helpers';\n\nimport type { BaseEntityRecords as _BaseEntityRecords } from './base-entity-records';\n\ndeclare module './base-entity-records' {\n\texport namespace BaseEntityRecords {\n\t\texport interface Plugin< C extends Context > {\n\t\t\t/**\n\t\t\t * The plugin file.\n\t\t\t */\n\t\t\tplugin: string;\n\t\t\t/**\n\t\t\t * The plugin activation status.\n\t\t\t */\n\t\t\tstatus: PluginStatus;\n\t\t\t/**\n\t\t\t * The plugin name.\n\t\t\t */\n\t\t\tname: string;\n\t\t\t/**\n\t\t\t * The plugin's website address.\n\t\t\t */\n\t\t\tplugin_uri: ContextualField< string, 'view' | 'edit', C >;\n\t\t\t/**\n\t\t\t * The plugin author.\n\t\t\t */\n\t\t\tauthor: ContextualField<\n\t\t\t\tRecord< string, string >,\n\t\t\t\t'view' | 'edit',\n\t\t\t\tC\n\t\t\t>;\n\t\t\t/**\n\t\t\t * Plugin author's website address.\n\t\t\t */\n\t\t\tauthor_uri: ContextualField< string, 'view' | 'edit', C >;\n\t\t\t/**\n\t\t\t * The plugin description.\n\t\t\t */\n\t\t\tdescription: ContextualField<\n\t\t\t\tRenderedText< 'edit' >,\n\t\t\t\t'view' | 'edit',\n\t\t\t\tC\n\t\t\t>;\n\t\t\t/**\n\t\t\t * The plugin version number.\n\t\t\t */\n\t\t\tversion: ContextualField< string, 'view' | 'edit', C >;\n\t\t\t/**\n\t\t\t * Whether the plugin can only be activated network-wide.\n\t\t\t */\n\t\t\tnetwork_only: boolean;\n\t\t\t/**\n\t\t\t * Minimum required version of WordPress.\n\t\t\t */\n\t\t\trequires_wp: string;\n\t\t\t/**\n\t\t\t * Minimum required version of PHP.\n\t\t\t */\n\t\t\trequires_php: string;\n\t\t\t/**\n\t\t\t * The plugin's text domain.\n\t\t\t */\n\t\t\ttextdomain: ContextualField< string, 'view' | 'edit', C >;\n\t\t}\n\t}\n}\n\nexport type PluginStatus = 'active' | 'inactive' | 'network-active';\nexport type Plugin< C extends Context = 'edit' > = OmitNevers<\n\t_BaseEntityRecords.Plugin< C >\n>;\n"],"mappings":"","ignoreList":[]}
@@ -4,7 +4,9 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.default = void 0;
7
+ exports.default = fetchLinkSuggestions;
8
+ exports.sortResults = sortResults;
9
+ exports.tokenize = tokenize;
8
10
  var _apiFetch = _interopRequireDefault(require("@wordpress/api-fetch"));
9
11
  var _url = require("@wordpress/url");
10
12
  var _htmlEntities = require("@wordpress/html-entities");
@@ -14,61 +16,14 @@ var _i18n = require("@wordpress/i18n");
14
16
  */
15
17
 
16
18
  /**
17
- * Filters the search by type
19
+ * Fetches link suggestions from the WordPress API.
18
20
  *
19
- * @typedef { 'attachment' | 'post' | 'term' | 'post-format' } WPLinkSearchType
20
- */
21
-
22
- /**
23
- * A link with an id may be of kind post-type or taxonomy
24
- *
25
- * @typedef { 'post-type' | 'taxonomy' } WPKind
26
- */
27
-
28
- /**
29
- * @typedef WPLinkSearchOptions
30
- *
31
- * @property {boolean} [isInitialSuggestions] Displays initial search suggestions, when true.
32
- * @property {WPLinkSearchType} [type] Filters by search type.
33
- * @property {string} [subtype] Slug of the post-type or taxonomy.
34
- * @property {number} [page] Which page of results to return.
35
- * @property {number} [perPage] Search results per page.
36
- */
37
-
38
- /**
39
- * @typedef WPLinkSearchResult
40
- *
41
- * @property {number} id Post or term id.
42
- * @property {string} url Link url.
43
- * @property {string} title Title of the link.
44
- * @property {string} type The taxonomy or post type slug or type URL.
45
- * @property {WPKind} [kind] Link kind of post-type or taxonomy
46
- */
47
-
48
- /**
49
- * @typedef WPLinkSearchResultAugments
50
- *
51
- * @property {{kind: WPKind}} [meta] Contains kind information.
52
- * @property {WPKind} [subtype] Optional subtype if it exists.
53
- */
54
-
55
- /**
56
- * @typedef {WPLinkSearchResult & WPLinkSearchResultAugments} WPLinkSearchResultAugmented
57
- */
58
-
59
- /**
60
- * @typedef WPEditorSettings
61
- *
62
- * @property {boolean} [ disablePostFormats ] Disables post formats, when true.
63
- */
64
-
65
- /**
66
- * Fetches link suggestions from the API.
21
+ * WordPress does not support searching multiple tables at once, e.g. posts and terms, so we
22
+ * perform multiple queries at the same time and then merge the results together.
67
23
  *
68
- * @async
69
- * @param {string} search
70
- * @param {WPLinkSearchOptions} [searchOptions]
71
- * @param {WPEditorSettings} [settings]
24
+ * @param search
25
+ * @param searchOptions
26
+ * @param editorSettings
72
27
  *
73
28
  * @example
74
29
  * ```js
@@ -83,31 +38,22 @@ var _i18n = require("@wordpress/i18n");
83
38
  * searchOptions
84
39
  * ) => fetchLinkSuggestions( search, searchOptions, settings );
85
40
  * ```
86
- * @return {Promise< WPLinkSearchResult[] >} List of search suggestions
87
41
  */
88
- const fetchLinkSuggestions = async (search, searchOptions = {}, settings = {}) => {
42
+ async function fetchLinkSuggestions(search, searchOptions = {}, editorSettings = {}) {
43
+ const searchOptionsToUse = searchOptions.isInitialSuggestions && searchOptions.initialSuggestionsSearchOptions ? {
44
+ ...searchOptions,
45
+ ...searchOptions.initialSuggestionsSearchOptions
46
+ } : searchOptions;
89
47
  const {
90
- isInitialSuggestions = false,
91
- initialSuggestionsSearchOptions = undefined
92
- } = searchOptions;
48
+ type,
49
+ subtype,
50
+ page,
51
+ perPage = searchOptions.isInitialSuggestions ? 3 : 20
52
+ } = searchOptionsToUse;
93
53
  const {
94
54
  disablePostFormats = false
95
- } = settings;
96
- let {
97
- type = undefined,
98
- subtype = undefined,
99
- page = undefined,
100
- perPage = isInitialSuggestions ? 3 : 20
101
- } = searchOptions;
102
-
103
- /** @type {Promise<WPLinkSearchResult>[]} */
55
+ } = editorSettings;
104
56
  const queries = [];
105
- if (isInitialSuggestions && initialSuggestionsSearchOptions) {
106
- type = initialSuggestionsSearchOptions.type || type;
107
- subtype = initialSuggestionsSearchOptions.subtype || subtype;
108
- page = initialSuggestionsSearchOptions.page || page;
109
- perPage = initialSuggestionsSearchOptions.perPage || perPage;
110
- }
111
57
  if (!type || type === 'post') {
112
58
  queries.push((0, _apiFetch.default)({
113
59
  path: (0, _url.addQueryArgs)('/wp/v2/search', {
@@ -120,11 +66,11 @@ const fetchLinkSuggestions = async (search, searchOptions = {}, settings = {}) =
120
66
  }).then(results => {
121
67
  return results.map(result => {
122
68
  return {
123
- ...result,
124
- meta: {
125
- kind: 'post-type',
126
- subtype
127
- }
69
+ id: result.id,
70
+ url: result.url,
71
+ title: (0, _htmlEntities.decodeEntities)(result.title || '') || (0, _i18n.__)('(no title)'),
72
+ type: result.subtype || result.type,
73
+ kind: 'post-type'
128
74
  };
129
75
  });
130
76
  }).catch(() => []) // Fail by returning no results.
@@ -142,11 +88,11 @@ const fetchLinkSuggestions = async (search, searchOptions = {}, settings = {}) =
142
88
  }).then(results => {
143
89
  return results.map(result => {
144
90
  return {
145
- ...result,
146
- meta: {
147
- kind: 'taxonomy',
148
- subtype
149
- }
91
+ id: result.id,
92
+ url: result.url,
93
+ title: (0, _htmlEntities.decodeEntities)(result.title || '') || (0, _i18n.__)('(no title)'),
94
+ type: result.subtype || result.type,
95
+ kind: 'taxonomy'
150
96
  };
151
97
  });
152
98
  }).catch(() => []) // Fail by returning no results.
@@ -164,11 +110,11 @@ const fetchLinkSuggestions = async (search, searchOptions = {}, settings = {}) =
164
110
  }).then(results => {
165
111
  return results.map(result => {
166
112
  return {
167
- ...result,
168
- meta: {
169
- kind: 'taxonomy',
170
- subtype
171
- }
113
+ id: result.id,
114
+ url: result.url,
115
+ title: (0, _htmlEntities.decodeEntities)(result.title || '') || (0, _i18n.__)('(no title)'),
116
+ type: result.subtype || result.type,
117
+ kind: 'taxonomy'
172
118
  };
173
119
  });
174
120
  }).catch(() => []) // Fail by returning no results.
@@ -184,38 +130,63 @@ const fetchLinkSuggestions = async (search, searchOptions = {}, settings = {}) =
184
130
  }).then(results => {
185
131
  return results.map(result => {
186
132
  return {
187
- ...result,
188
- meta: {
189
- kind: 'media'
190
- }
133
+ id: result.id,
134
+ url: result.source_url,
135
+ title: (0, _htmlEntities.decodeEntities)(result.title.rendered || '') || (0, _i18n.__)('(no title)'),
136
+ type: result.type,
137
+ kind: 'media'
191
138
  };
192
139
  });
193
140
  }).catch(() => []) // Fail by returning no results.
194
141
  );
195
142
  }
196
- return Promise.all(queries).then(results => {
197
- return results.reduce(( /** @type {WPLinkSearchResult[]} */accumulator, current) => accumulator.concat(current),
198
- // Flatten list.
199
- []).filter(
200
- /**
201
- * @param {{ id: number }} result
202
- */
203
- result => {
204
- return !!result.id;
205
- }).slice(0, perPage).map(( /** @type {WPLinkSearchResultAugmented} */result) => {
206
- const isMedia = result.type === 'attachment';
207
- return {
208
- id: result.id,
209
- // @ts-ignore fix when we make this a TS file
210
- url: isMedia ? result.source_url : result.url,
211
- title: (0, _htmlEntities.decodeEntities)(isMedia ?
212
- // @ts-ignore fix when we make this a TS file
213
- result.title.rendered : result.title || '') || (0, _i18n.__)('(no title)'),
214
- type: result.subtype || result.type,
215
- kind: result?.meta?.kind
216
- };
217
- });
218
- });
219
- };
220
- var _default = exports.default = fetchLinkSuggestions;
143
+ const responses = await Promise.all(queries);
144
+ let results = responses.flat();
145
+ results = results.filter(result => !!result.id);
146
+ results = sortResults(results, search);
147
+ results = results.slice(0, perPage);
148
+ return results;
149
+ }
150
+
151
+ /**
152
+ * Sort search results by relevance to the given query.
153
+ *
154
+ * Sorting is necessary as we're querying multiple endpoints and merging the results. For example
155
+ * a taxonomy title might be more relevant than a post title, but by default taxonomy results will
156
+ * be ordered after all the (potentially irrelevant) post results.
157
+ *
158
+ * We sort by scoring each result, where the score is the number of tokens in the title that are
159
+ * also in the search query, divided by the total number of tokens in the title. This gives us a
160
+ * score between 0 and 1, where 1 is a perfect match.
161
+ *
162
+ * @param results
163
+ * @param search
164
+ */
165
+ function sortResults(results, search) {
166
+ const searchTokens = new Set(tokenize(search));
167
+ const scores = {};
168
+ for (const result of results) {
169
+ if (result.title) {
170
+ const titleTokens = tokenize(result.title);
171
+ const matchingTokens = titleTokens.filter(token => searchTokens.has(token));
172
+ scores[result.id] = matchingTokens.length / titleTokens.length;
173
+ } else {
174
+ scores[result.id] = 0;
175
+ }
176
+ }
177
+ return results.sort((a, b) => scores[b.id] - scores[a.id]);
178
+ }
179
+
180
+ /**
181
+ * Turns text into an array of tokens, with whitespace and punctuation removed.
182
+ *
183
+ * For example, `"I'm having a ball."` becomes `[ "im", "having", "a", "ball" ]`.
184
+ *
185
+ * @param text
186
+ */
187
+ function tokenize(text) {
188
+ // \p{L} matches any kind of letter from any language.
189
+ // \p{N} matches any kind of numeric character.
190
+ return text.toLowerCase().match(/[\p{L}\p{N}]+/gu) || [];
191
+ }
221
192
  //# sourceMappingURL=__experimental-fetch-link-suggestions.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_apiFetch","_interopRequireDefault","require","_url","_htmlEntities","_i18n","fetchLinkSuggestions","search","searchOptions","settings","isInitialSuggestions","initialSuggestionsSearchOptions","undefined","disablePostFormats","type","subtype","page","perPage","queries","push","apiFetch","path","addQueryArgs","per_page","then","results","map","result","meta","kind","catch","Promise","all","reduce","accumulator","current","concat","filter","id","slice","isMedia","url","source_url","title","decodeEntities","rendered","__","_default","exports","default"],"sources":["@wordpress/core-data/src/fetch/__experimental-fetch-link-suggestions.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport apiFetch from '@wordpress/api-fetch';\nimport { addQueryArgs } from '@wordpress/url';\nimport { decodeEntities } from '@wordpress/html-entities';\nimport { __ } from '@wordpress/i18n';\n\n/**\n * Filters the search by type\n *\n * @typedef { 'attachment' | 'post' | 'term' | 'post-format' } WPLinkSearchType\n */\n\n/**\n * A link with an id may be of kind post-type or taxonomy\n *\n * @typedef { 'post-type' | 'taxonomy' } WPKind\n */\n\n/**\n * @typedef WPLinkSearchOptions\n *\n * @property {boolean} [isInitialSuggestions] Displays initial search suggestions, when true.\n * @property {WPLinkSearchType} [type] Filters by search type.\n * @property {string} [subtype] Slug of the post-type or taxonomy.\n * @property {number} [page] Which page of results to return.\n * @property {number} [perPage] Search results per page.\n */\n\n/**\n * @typedef WPLinkSearchResult\n *\n * @property {number} id Post or term id.\n * @property {string} url Link url.\n * @property {string} title Title of the link.\n * @property {string} type The taxonomy or post type slug or type URL.\n * @property {WPKind} [kind] Link kind of post-type or taxonomy\n */\n\n/**\n * @typedef WPLinkSearchResultAugments\n *\n * @property {{kind: WPKind}} [meta] Contains kind information.\n * @property {WPKind} [subtype] Optional subtype if it exists.\n */\n\n/**\n * @typedef {WPLinkSearchResult & WPLinkSearchResultAugments} WPLinkSearchResultAugmented\n */\n\n/**\n * @typedef WPEditorSettings\n *\n * @property {boolean} [ disablePostFormats ] Disables post formats, when true.\n */\n\n/**\n * Fetches link suggestions from the API.\n *\n * @async\n * @param {string} search\n * @param {WPLinkSearchOptions} [searchOptions]\n * @param {WPEditorSettings} [settings]\n *\n * @example\n * ```js\n * import { __experimentalFetchLinkSuggestions as fetchLinkSuggestions } from '@wordpress/core-data';\n *\n * //...\n *\n * export function initialize( id, settings ) {\n *\n * settings.__experimentalFetchLinkSuggestions = (\n * search,\n * searchOptions\n * ) => fetchLinkSuggestions( search, searchOptions, settings );\n * ```\n * @return {Promise< WPLinkSearchResult[] >} List of search suggestions\n */\nconst fetchLinkSuggestions = async (\n\tsearch,\n\tsearchOptions = {},\n\tsettings = {}\n) => {\n\tconst {\n\t\tisInitialSuggestions = false,\n\t\tinitialSuggestionsSearchOptions = undefined,\n\t} = searchOptions;\n\n\tconst { disablePostFormats = false } = settings;\n\n\tlet {\n\t\ttype = undefined,\n\t\tsubtype = undefined,\n\t\tpage = undefined,\n\t\tperPage = isInitialSuggestions ? 3 : 20,\n\t} = searchOptions;\n\n\t/** @type {Promise<WPLinkSearchResult>[]} */\n\tconst queries = [];\n\n\tif ( isInitialSuggestions && initialSuggestionsSearchOptions ) {\n\t\ttype = initialSuggestionsSearchOptions.type || type;\n\t\tsubtype = initialSuggestionsSearchOptions.subtype || subtype;\n\t\tpage = initialSuggestionsSearchOptions.page || page;\n\t\tperPage = initialSuggestionsSearchOptions.perPage || perPage;\n\t}\n\n\tif ( ! type || type === 'post' ) {\n\t\tqueries.push(\n\t\t\tapiFetch( {\n\t\t\t\tpath: addQueryArgs( '/wp/v2/search', {\n\t\t\t\t\tsearch,\n\t\t\t\t\tpage,\n\t\t\t\t\tper_page: perPage,\n\t\t\t\t\ttype: 'post',\n\t\t\t\t\tsubtype,\n\t\t\t\t} ),\n\t\t\t} )\n\t\t\t\t.then( ( results ) => {\n\t\t\t\t\treturn results.map( ( result ) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...result,\n\t\t\t\t\t\t\tmeta: { kind: 'post-type', subtype },\n\t\t\t\t\t\t};\n\t\t\t\t\t} );\n\t\t\t\t} )\n\t\t\t\t.catch( () => [] ) // Fail by returning no results.\n\t\t);\n\t}\n\n\tif ( ! type || type === 'term' ) {\n\t\tqueries.push(\n\t\t\tapiFetch( {\n\t\t\t\tpath: addQueryArgs( '/wp/v2/search', {\n\t\t\t\t\tsearch,\n\t\t\t\t\tpage,\n\t\t\t\t\tper_page: perPage,\n\t\t\t\t\ttype: 'term',\n\t\t\t\t\tsubtype,\n\t\t\t\t} ),\n\t\t\t} )\n\t\t\t\t.then( ( results ) => {\n\t\t\t\t\treturn results.map( ( result ) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...result,\n\t\t\t\t\t\t\tmeta: { kind: 'taxonomy', subtype },\n\t\t\t\t\t\t};\n\t\t\t\t\t} );\n\t\t\t\t} )\n\t\t\t\t.catch( () => [] ) // Fail by returning no results.\n\t\t);\n\t}\n\n\tif ( ! disablePostFormats && ( ! type || type === 'post-format' ) ) {\n\t\tqueries.push(\n\t\t\tapiFetch( {\n\t\t\t\tpath: addQueryArgs( '/wp/v2/search', {\n\t\t\t\t\tsearch,\n\t\t\t\t\tpage,\n\t\t\t\t\tper_page: perPage,\n\t\t\t\t\ttype: 'post-format',\n\t\t\t\t\tsubtype,\n\t\t\t\t} ),\n\t\t\t} )\n\t\t\t\t.then( ( results ) => {\n\t\t\t\t\treturn results.map( ( result ) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...result,\n\t\t\t\t\t\t\tmeta: { kind: 'taxonomy', subtype },\n\t\t\t\t\t\t};\n\t\t\t\t\t} );\n\t\t\t\t} )\n\t\t\t\t.catch( () => [] ) // Fail by returning no results.\n\t\t);\n\t}\n\n\tif ( ! type || type === 'attachment' ) {\n\t\tqueries.push(\n\t\t\tapiFetch( {\n\t\t\t\tpath: addQueryArgs( '/wp/v2/media', {\n\t\t\t\t\tsearch,\n\t\t\t\t\tpage,\n\t\t\t\t\tper_page: perPage,\n\t\t\t\t} ),\n\t\t\t} )\n\t\t\t\t.then( ( results ) => {\n\t\t\t\t\treturn results.map( ( result ) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...result,\n\t\t\t\t\t\t\tmeta: { kind: 'media' },\n\t\t\t\t\t\t};\n\t\t\t\t\t} );\n\t\t\t\t} )\n\t\t\t\t.catch( () => [] ) // Fail by returning no results.\n\t\t);\n\t}\n\n\treturn Promise.all( queries ).then( ( results ) => {\n\t\treturn results\n\t\t\t.reduce(\n\t\t\t\t( /** @type {WPLinkSearchResult[]} */ accumulator, current ) =>\n\t\t\t\t\taccumulator.concat( current ), // Flatten list.\n\t\t\t\t[]\n\t\t\t)\n\t\t\t.filter(\n\t\t\t\t/**\n\t\t\t\t * @param {{ id: number }} result\n\t\t\t\t */\n\t\t\t\t( result ) => {\n\t\t\t\t\treturn !! result.id;\n\t\t\t\t}\n\t\t\t)\n\t\t\t.slice( 0, perPage )\n\t\t\t.map( ( /** @type {WPLinkSearchResultAugmented} */ result ) => {\n\t\t\t\tconst isMedia = result.type === 'attachment';\n\n\t\t\t\treturn {\n\t\t\t\t\tid: result.id,\n\t\t\t\t\t// @ts-ignore fix when we make this a TS file\n\t\t\t\t\turl: isMedia ? result.source_url : result.url,\n\t\t\t\t\ttitle:\n\t\t\t\t\t\tdecodeEntities(\n\t\t\t\t\t\t\tisMedia\n\t\t\t\t\t\t\t\t? // @ts-ignore fix when we make this a TS file\n\t\t\t\t\t\t\t\t result.title.rendered\n\t\t\t\t\t\t\t\t: result.title || ''\n\t\t\t\t\t\t) || __( '(no title)' ),\n\t\t\t\t\ttype: result.subtype || result.type,\n\t\t\t\t\tkind: result?.meta?.kind,\n\t\t\t\t};\n\t\t\t} );\n\t} );\n};\n\nexport default fetchLinkSuggestions;\n"],"mappings":";;;;;;;AAGA,IAAAA,SAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,IAAA,GAAAD,OAAA;AACA,IAAAE,aAAA,GAAAF,OAAA;AACA,IAAAG,KAAA,GAAAH,OAAA;AANA;AACA;AACA;;AAMA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMI,oBAAoB,GAAG,MAAAA,CAC5BC,MAAM,EACNC,aAAa,GAAG,CAAC,CAAC,EAClBC,QAAQ,GAAG,CAAC,CAAC,KACT;EACJ,MAAM;IACLC,oBAAoB,GAAG,KAAK;IAC5BC,+BAA+B,GAAGC;EACnC,CAAC,GAAGJ,aAAa;EAEjB,MAAM;IAAEK,kBAAkB,GAAG;EAAM,CAAC,GAAGJ,QAAQ;EAE/C,IAAI;IACHK,IAAI,GAAGF,SAAS;IAChBG,OAAO,GAAGH,SAAS;IACnBI,IAAI,GAAGJ,SAAS;IAChBK,OAAO,GAAGP,oBAAoB,GAAG,CAAC,GAAG;EACtC,CAAC,GAAGF,aAAa;;EAEjB;EACA,MAAMU,OAAO,GAAG,EAAE;EAElB,IAAKR,oBAAoB,IAAIC,+BAA+B,EAAG;IAC9DG,IAAI,GAAGH,+BAA+B,CAACG,IAAI,IAAIA,IAAI;IACnDC,OAAO,GAAGJ,+BAA+B,CAACI,OAAO,IAAIA,OAAO;IAC5DC,IAAI,GAAGL,+BAA+B,CAACK,IAAI,IAAIA,IAAI;IACnDC,OAAO,GAAGN,+BAA+B,CAACM,OAAO,IAAIA,OAAO;EAC7D;EAEA,IAAK,CAAEH,IAAI,IAAIA,IAAI,KAAK,MAAM,EAAG;IAChCI,OAAO,CAACC,IAAI,CACX,IAAAC,iBAAQ,EAAE;MACTC,IAAI,EAAE,IAAAC,iBAAY,EAAE,eAAe,EAAE;QACpCf,MAAM;QACNS,IAAI;QACJO,QAAQ,EAAEN,OAAO;QACjBH,IAAI,EAAE,MAAM;QACZC;MACD,CAAE;IACH,CAAE,CAAC,CACDS,IAAI,CAAIC,OAAO,IAAM;MACrB,OAAOA,OAAO,CAACC,GAAG,CAAIC,MAAM,IAAM;QACjC,OAAO;UACN,GAAGA,MAAM;UACTC,IAAI,EAAE;YAAEC,IAAI,EAAE,WAAW;YAAEd;UAAQ;QACpC,CAAC;MACF,CAAE,CAAC;IACJ,CAAE,CAAC,CACFe,KAAK,CAAE,MAAM,EAAG,CAAC,CAAC;IACrB,CAAC;EACF;EAEA,IAAK,CAAEhB,IAAI,IAAIA,IAAI,KAAK,MAAM,EAAG;IAChCI,OAAO,CAACC,IAAI,CACX,IAAAC,iBAAQ,EAAE;MACTC,IAAI,EAAE,IAAAC,iBAAY,EAAE,eAAe,EAAE;QACpCf,MAAM;QACNS,IAAI;QACJO,QAAQ,EAAEN,OAAO;QACjBH,IAAI,EAAE,MAAM;QACZC;MACD,CAAE;IACH,CAAE,CAAC,CACDS,IAAI,CAAIC,OAAO,IAAM;MACrB,OAAOA,OAAO,CAACC,GAAG,CAAIC,MAAM,IAAM;QACjC,OAAO;UACN,GAAGA,MAAM;UACTC,IAAI,EAAE;YAAEC,IAAI,EAAE,UAAU;YAAEd;UAAQ;QACnC,CAAC;MACF,CAAE,CAAC;IACJ,CAAE,CAAC,CACFe,KAAK,CAAE,MAAM,EAAG,CAAC,CAAC;IACrB,CAAC;EACF;EAEA,IAAK,CAAEjB,kBAAkB,KAAM,CAAEC,IAAI,IAAIA,IAAI,KAAK,aAAa,CAAE,EAAG;IACnEI,OAAO,CAACC,IAAI,CACX,IAAAC,iBAAQ,EAAE;MACTC,IAAI,EAAE,IAAAC,iBAAY,EAAE,eAAe,EAAE;QACpCf,MAAM;QACNS,IAAI;QACJO,QAAQ,EAAEN,OAAO;QACjBH,IAAI,EAAE,aAAa;QACnBC;MACD,CAAE;IACH,CAAE,CAAC,CACDS,IAAI,CAAIC,OAAO,IAAM;MACrB,OAAOA,OAAO,CAACC,GAAG,CAAIC,MAAM,IAAM;QACjC,OAAO;UACN,GAAGA,MAAM;UACTC,IAAI,EAAE;YAAEC,IAAI,EAAE,UAAU;YAAEd;UAAQ;QACnC,CAAC;MACF,CAAE,CAAC;IACJ,CAAE,CAAC,CACFe,KAAK,CAAE,MAAM,EAAG,CAAC,CAAC;IACrB,CAAC;EACF;EAEA,IAAK,CAAEhB,IAAI,IAAIA,IAAI,KAAK,YAAY,EAAG;IACtCI,OAAO,CAACC,IAAI,CACX,IAAAC,iBAAQ,EAAE;MACTC,IAAI,EAAE,IAAAC,iBAAY,EAAE,cAAc,EAAE;QACnCf,MAAM;QACNS,IAAI;QACJO,QAAQ,EAAEN;MACX,CAAE;IACH,CAAE,CAAC,CACDO,IAAI,CAAIC,OAAO,IAAM;MACrB,OAAOA,OAAO,CAACC,GAAG,CAAIC,MAAM,IAAM;QACjC,OAAO;UACN,GAAGA,MAAM;UACTC,IAAI,EAAE;YAAEC,IAAI,EAAE;UAAQ;QACvB,CAAC;MACF,CAAE,CAAC;IACJ,CAAE,CAAC,CACFC,KAAK,CAAE,MAAM,EAAG,CAAC,CAAC;IACrB,CAAC;EACF;EAEA,OAAOC,OAAO,CAACC,GAAG,CAAEd,OAAQ,CAAC,CAACM,IAAI,CAAIC,OAAO,IAAM;IAClD,OAAOA,OAAO,CACZQ,MAAM,CACN,EAAE,mCAAoCC,WAAW,EAAEC,OAAO,KACzDD,WAAW,CAACE,MAAM,CAAED,OAAQ,CAAC;IAAE;IAChC,EACD,CAAC,CACAE,MAAM;IACN;AACJ;AACA;IACMV,MAAM,IAAM;MACb,OAAO,CAAC,CAAEA,MAAM,CAACW,EAAE;IACpB,CACD,CAAC,CACAC,KAAK,CAAE,CAAC,EAAEtB,OAAQ,CAAC,CACnBS,GAAG,CAAE,EAAE,0CAA2CC,MAAM,KAAM;MAC9D,MAAMa,OAAO,GAAGb,MAAM,CAACb,IAAI,KAAK,YAAY;MAE5C,OAAO;QACNwB,EAAE,EAAEX,MAAM,CAACW,EAAE;QACb;QACAG,GAAG,EAAED,OAAO,GAAGb,MAAM,CAACe,UAAU,GAAGf,MAAM,CAACc,GAAG;QAC7CE,KAAK,EACJ,IAAAC,4BAAc,EACbJ,OAAO;QACJ;QACAb,MAAM,CAACgB,KAAK,CAACE,QAAQ,GACrBlB,MAAM,CAACgB,KAAK,IAAI,EACpB,CAAC,IAAI,IAAAG,QAAE,EAAE,YAAa,CAAC;QACxBhC,IAAI,EAAEa,MAAM,CAACZ,OAAO,IAAIY,MAAM,CAACb,IAAI;QACnCe,IAAI,EAAEF,MAAM,EAAEC,IAAI,EAAEC;MACrB,CAAC;IACF,CAAE,CAAC;EACL,CAAE,CAAC;AACJ,CAAC;AAAC,IAAAkB,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEa3C,oBAAoB","ignoreList":[]}
1
+ {"version":3,"names":["_apiFetch","_interopRequireDefault","require","_url","_htmlEntities","_i18n","fetchLinkSuggestions","search","searchOptions","editorSettings","searchOptionsToUse","isInitialSuggestions","initialSuggestionsSearchOptions","type","subtype","page","perPage","disablePostFormats","queries","push","apiFetch","path","addQueryArgs","per_page","then","results","map","result","id","url","title","decodeEntities","__","kind","catch","source_url","rendered","responses","Promise","all","flat","filter","sortResults","slice","searchTokens","Set","tokenize","scores","titleTokens","matchingTokens","token","has","length","sort","a","b","text","toLowerCase","match"],"sources":["@wordpress/core-data/src/fetch/__experimental-fetch-link-suggestions.ts"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport apiFetch from '@wordpress/api-fetch';\nimport { addQueryArgs } from '@wordpress/url';\nimport { decodeEntities } from '@wordpress/html-entities';\nimport { __ } from '@wordpress/i18n';\n\nexport type SearchOptions = {\n\t/**\n\t * Displays initial search suggestions, when true.\n\t */\n\tisInitialSuggestions?: boolean;\n\t/**\n\t * Search options for initial suggestions.\n\t */\n\tinitialSuggestionsSearchOptions?: Omit<\n\t\tSearchOptions,\n\t\t'isInitialSuggestions' | 'initialSuggestionsSearchOptions'\n\t>;\n\t/**\n\t * Filters by search type.\n\t */\n\ttype?: 'attachment' | 'post' | 'term' | 'post-format';\n\t/**\n\t * Slug of the post-type or taxonomy.\n\t */\n\tsubtype?: string;\n\t/**\n\t * Which page of results to return.\n\t */\n\tpage?: number;\n\t/**\n\t * Search results per page.\n\t */\n\tperPage?: number;\n};\n\nexport type EditorSettings = {\n\t/**\n\t * Disables post formats, when true.\n\t */\n\tdisablePostFormats?: boolean;\n};\n\ntype SearchAPIResult = {\n\tid: number;\n\ttitle: string;\n\turl: string;\n\ttype: string;\n\tsubtype: string;\n};\n\ntype MediaAPIResult = {\n\tid: number;\n\ttitle: { rendered: string };\n\tsource_url: string;\n\ttype: string;\n};\n\nexport type SearchResult = {\n\t/**\n\t * Post or term id.\n\t */\n\tid: number;\n\t/**\n\t * Link url.\n\t */\n\turl: string;\n\t/**\n\t * Title of the link.\n\t */\n\ttitle: string;\n\t/**\n\t * The taxonomy or post type slug or type URL.\n\t */\n\ttype: string;\n\t/**\n\t * Link kind of post-type or taxonomy\n\t */\n\tkind?: string;\n};\n\n/**\n * Fetches link suggestions from the WordPress API.\n *\n * WordPress does not support searching multiple tables at once, e.g. posts and terms, so we\n * perform multiple queries at the same time and then merge the results together.\n *\n * @param search\n * @param searchOptions\n * @param editorSettings\n *\n * @example\n * ```js\n * import { __experimentalFetchLinkSuggestions as fetchLinkSuggestions } from '@wordpress/core-data';\n *\n * //...\n *\n * export function initialize( id, settings ) {\n *\n * settings.__experimentalFetchLinkSuggestions = (\n * search,\n * searchOptions\n * ) => fetchLinkSuggestions( search, searchOptions, settings );\n * ```\n */\nexport default async function fetchLinkSuggestions(\n\tsearch: string,\n\tsearchOptions: SearchOptions = {},\n\teditorSettings: EditorSettings = {}\n): Promise< SearchResult[] > {\n\tconst searchOptionsToUse =\n\t\tsearchOptions.isInitialSuggestions &&\n\t\tsearchOptions.initialSuggestionsSearchOptions\n\t\t\t? {\n\t\t\t\t\t...searchOptions,\n\t\t\t\t\t...searchOptions.initialSuggestionsSearchOptions,\n\t\t\t }\n\t\t\t: searchOptions;\n\n\tconst {\n\t\ttype,\n\t\tsubtype,\n\t\tpage,\n\t\tperPage = searchOptions.isInitialSuggestions ? 3 : 20,\n\t} = searchOptionsToUse;\n\n\tconst { disablePostFormats = false } = editorSettings;\n\n\tconst queries: Promise< SearchResult[] >[] = [];\n\n\tif ( ! type || type === 'post' ) {\n\t\tqueries.push(\n\t\t\tapiFetch< SearchAPIResult[] >( {\n\t\t\t\tpath: addQueryArgs( '/wp/v2/search', {\n\t\t\t\t\tsearch,\n\t\t\t\t\tpage,\n\t\t\t\t\tper_page: perPage,\n\t\t\t\t\ttype: 'post',\n\t\t\t\t\tsubtype,\n\t\t\t\t} ),\n\t\t\t} )\n\t\t\t\t.then( ( results ) => {\n\t\t\t\t\treturn results.map( ( result ) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tid: result.id,\n\t\t\t\t\t\t\turl: result.url,\n\t\t\t\t\t\t\ttitle:\n\t\t\t\t\t\t\t\tdecodeEntities( result.title || '' ) ||\n\t\t\t\t\t\t\t\t__( '(no title)' ),\n\t\t\t\t\t\t\ttype: result.subtype || result.type,\n\t\t\t\t\t\t\tkind: 'post-type',\n\t\t\t\t\t\t};\n\t\t\t\t\t} );\n\t\t\t\t} )\n\t\t\t\t.catch( () => [] ) // Fail by returning no results.\n\t\t);\n\t}\n\n\tif ( ! type || type === 'term' ) {\n\t\tqueries.push(\n\t\t\tapiFetch< SearchAPIResult[] >( {\n\t\t\t\tpath: addQueryArgs( '/wp/v2/search', {\n\t\t\t\t\tsearch,\n\t\t\t\t\tpage,\n\t\t\t\t\tper_page: perPage,\n\t\t\t\t\ttype: 'term',\n\t\t\t\t\tsubtype,\n\t\t\t\t} ),\n\t\t\t} )\n\t\t\t\t.then( ( results ) => {\n\t\t\t\t\treturn results.map( ( result ) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tid: result.id,\n\t\t\t\t\t\t\turl: result.url,\n\t\t\t\t\t\t\ttitle:\n\t\t\t\t\t\t\t\tdecodeEntities( result.title || '' ) ||\n\t\t\t\t\t\t\t\t__( '(no title)' ),\n\t\t\t\t\t\t\ttype: result.subtype || result.type,\n\t\t\t\t\t\t\tkind: 'taxonomy',\n\t\t\t\t\t\t};\n\t\t\t\t\t} );\n\t\t\t\t} )\n\t\t\t\t.catch( () => [] ) // Fail by returning no results.\n\t\t);\n\t}\n\n\tif ( ! disablePostFormats && ( ! type || type === 'post-format' ) ) {\n\t\tqueries.push(\n\t\t\tapiFetch< SearchAPIResult[] >( {\n\t\t\t\tpath: addQueryArgs( '/wp/v2/search', {\n\t\t\t\t\tsearch,\n\t\t\t\t\tpage,\n\t\t\t\t\tper_page: perPage,\n\t\t\t\t\ttype: 'post-format',\n\t\t\t\t\tsubtype,\n\t\t\t\t} ),\n\t\t\t} )\n\t\t\t\t.then( ( results ) => {\n\t\t\t\t\treturn results.map( ( result ) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tid: result.id,\n\t\t\t\t\t\t\turl: result.url,\n\t\t\t\t\t\t\ttitle:\n\t\t\t\t\t\t\t\tdecodeEntities( result.title || '' ) ||\n\t\t\t\t\t\t\t\t__( '(no title)' ),\n\t\t\t\t\t\t\ttype: result.subtype || result.type,\n\t\t\t\t\t\t\tkind: 'taxonomy',\n\t\t\t\t\t\t};\n\t\t\t\t\t} );\n\t\t\t\t} )\n\t\t\t\t.catch( () => [] ) // Fail by returning no results.\n\t\t);\n\t}\n\n\tif ( ! type || type === 'attachment' ) {\n\t\tqueries.push(\n\t\t\tapiFetch< MediaAPIResult[] >( {\n\t\t\t\tpath: addQueryArgs( '/wp/v2/media', {\n\t\t\t\t\tsearch,\n\t\t\t\t\tpage,\n\t\t\t\t\tper_page: perPage,\n\t\t\t\t} ),\n\t\t\t} )\n\t\t\t\t.then( ( results ) => {\n\t\t\t\t\treturn results.map( ( result ) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tid: result.id,\n\t\t\t\t\t\t\turl: result.source_url,\n\t\t\t\t\t\t\ttitle:\n\t\t\t\t\t\t\t\tdecodeEntities( result.title.rendered || '' ) ||\n\t\t\t\t\t\t\t\t__( '(no title)' ),\n\t\t\t\t\t\t\ttype: result.type,\n\t\t\t\t\t\t\tkind: 'media',\n\t\t\t\t\t\t};\n\t\t\t\t\t} );\n\t\t\t\t} )\n\t\t\t\t.catch( () => [] ) // Fail by returning no results.\n\t\t);\n\t}\n\n\tconst responses = await Promise.all( queries );\n\n\tlet results = responses.flat();\n\tresults = results.filter( ( result ) => !! result.id );\n\tresults = sortResults( results, search );\n\tresults = results.slice( 0, perPage );\n\treturn results;\n}\n\n/**\n * Sort search results by relevance to the given query.\n *\n * Sorting is necessary as we're querying multiple endpoints and merging the results. For example\n * a taxonomy title might be more relevant than a post title, but by default taxonomy results will\n * be ordered after all the (potentially irrelevant) post results.\n *\n * We sort by scoring each result, where the score is the number of tokens in the title that are\n * also in the search query, divided by the total number of tokens in the title. This gives us a\n * score between 0 and 1, where 1 is a perfect match.\n *\n * @param results\n * @param search\n */\nexport function sortResults( results: SearchResult[], search: string ) {\n\tconst searchTokens = new Set( tokenize( search ) );\n\n\tconst scores = {};\n\tfor ( const result of results ) {\n\t\tif ( result.title ) {\n\t\t\tconst titleTokens = tokenize( result.title );\n\t\t\tconst matchingTokens = titleTokens.filter( ( token ) =>\n\t\t\t\tsearchTokens.has( token )\n\t\t\t);\n\t\t\tscores[ result.id ] = matchingTokens.length / titleTokens.length;\n\t\t} else {\n\t\t\tscores[ result.id ] = 0;\n\t\t}\n\t}\n\n\treturn results.sort( ( a, b ) => scores[ b.id ] - scores[ a.id ] );\n}\n\n/**\n * Turns text into an array of tokens, with whitespace and punctuation removed.\n *\n * For example, `\"I'm having a ball.\"` becomes `[ \"im\", \"having\", \"a\", \"ball\" ]`.\n *\n * @param text\n */\nexport function tokenize( text: string ): string[] {\n\t// \\p{L} matches any kind of letter from any language.\n\t// \\p{N} matches any kind of numeric character.\n\treturn text.toLowerCase().match( /[\\p{L}\\p{N}]+/gu ) || [];\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["@wordpress/core-data/src/entity-types/helpers.ts"],"sourcesContent":["/**\n * Internal dependencies\n */\nimport type { EntityRecord } from './index';\n\nexport interface AvatarUrls {\n\t/**\n\t * Avatar URL with image size of 24 pixels.\n\t */\n\t'24': string;\n\t/**\n\t * Avatar URL with image size of 48 pixels.\n\t */\n\t'48': string;\n\t/**\n\t * Avatar URL with image size of 96 pixels.\n\t */\n\t'96': string;\n}\n\nexport type MediaType = 'image' | 'file';\nexport type CommentingStatus = 'open' | 'closed';\nexport type PingStatus = 'open' | 'closed';\nexport type PostStatus = 'publish' | 'future' | 'draft' | 'pending' | 'private';\nexport type PostFormat =\n\t| 'standard'\n\t| 'aside'\n\t| 'chat'\n\t| 'gallery'\n\t| 'link'\n\t| 'image'\n\t| 'quote'\n\t| 'status'\n\t| 'video'\n\t| 'audio';\n\n/**\n * The REST API context parameter.\n */\nexport type Context = 'view' | 'edit' | 'embed';\n\n/**\n * ContextualField makes the field available only in the specified given contexts,\n * and ensure the field is absent from the object when in a different context.\n *\n * @example\n * ```ts\n * interface Post< C extends Context > {\n * \t…\n * \tmodified: ContextualField< string, 'edit' | 'view', C >;\n * \tpassword: ContextualField< string, 'edit', C >;\n * \t…\n * }\n *\n * const post: Post<'edit'> = …\n * // post.modified exists as a string\n * // post.password exists as a string\n *\n * const post: Post<'view'> = …\n * // post.modified still exists as a string\n * // post.password is missing, undefined, because we're not in the `edit` context.\n * ```\n */\nexport type ContextualField<\n\tFieldType,\n\tAvailableInContexts extends Context,\n\tC extends Context,\n> = AvailableInContexts extends C ? FieldType : never;\n\n/**\n * Removes all the properties of type never, even the deeply nested ones.\n *\n * @example\n * ```ts\n * type MyType = {\n * foo: string;\n * bar: never;\n * nested: {\n * foo: string;\n * bar: never;\n * }\n * }\n * const x = {} as OmitNevers<MyType>;\n * // x is of type { foo: string; nested: { foo: string; }}\n * // The `never` properties were removed entirely\n * ```\n */\nexport type OmitNevers<\n\tT,\n\tNevers = {\n\t\t[ K in keyof T ]: Exclude< T[ K ], undefined > extends never\n\t\t\t? never\n\t\t\t: T[ K ] extends Record< string, unknown >\n\t\t\t? OmitNevers< T[ K ] >\n\t\t\t: T[ K ];\n\t},\n> = Pick<\n\tNevers,\n\t{\n\t\t[ K in keyof Nevers ]: Nevers[ K ] extends never ? never : K;\n\t}[ keyof Nevers ]\n>;\n\n/**\n * A string that the server renders which often involves\n * modifications from the raw source string.\n *\n * For example, block HTML with the comment delimiters exists\n * in `post_content` but those comments are stripped out when\n * rendering to a page view. Similarly, plugins might modify\n * content or replace shortcodes.\n */\nexport interface RenderedText< C extends Context > {\n\t/**\n\t * The source string which will be rendered on page views.\n\t */\n\traw: ContextualField< string, 'edit', C >;\n\t/**\n\t * The output of the raw source after processing and filtering on the server.\n\t */\n\trendered: string;\n}\n\n/**\n * Updatable<EntityRecord> is a type describing Edited Entity Records. They are like\n * regular Entity Records, but they have all the local edits applied on top of the REST API data.\n *\n * This turns certain field from an object into a string.\n *\n * Entities like Post have fields that only be rendered on the server, like title, excerpt,\n * and content. The REST API exposes both the raw markup and the rendered version of those fields.\n * For example, in the block editor, content.rendered could used as a visual preview, and\n * content.raw could be used to populate the code editor.\n *\n * When updating these rendered fields, Javascript is not be able to properly render arbitrary block\n * markup. Therefore, it stores only the raw markup without the rendered part. And since that's a string,\n * the entire field becomes a string.\n *\n * @example\n * ```ts\n * type Post< C extends Context > {\n * title: RenderedText< C >;\n * }\n * const post = {} as Post;\n * // post.title is an object with raw and rendered properties\n *\n * const updatablePost = {} as Updatable< Post >;\n * // updatablePost.title is a string\n * ```\n */\nexport type Updatable< T extends EntityRecord< 'edit' > > = {\n\t[ K in keyof T ]: T[ K ] extends RenderedText< any > ? string : T[ K ];\n};\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["@wordpress/core-data/src/entity-types/helpers.ts"],"sourcesContent":["/**\n * Internal dependencies\n */\nimport type { EntityRecord } from './index';\n\nexport interface AvatarUrls {\n\t/**\n\t * Avatar URL with image size of 24 pixels.\n\t */\n\t'24': string;\n\t/**\n\t * Avatar URL with image size of 48 pixels.\n\t */\n\t'48': string;\n\t/**\n\t * Avatar URL with image size of 96 pixels.\n\t */\n\t'96': string;\n}\n\nexport type MediaType = 'image' | 'file';\nexport type CommentingStatus = 'open' | 'closed';\nexport type PingStatus = 'open' | 'closed';\nexport type PostStatus = 'publish' | 'future' | 'draft' | 'pending' | 'private';\nexport type PostFormat =\n\t| 'standard'\n\t| 'aside'\n\t| 'chat'\n\t| 'gallery'\n\t| 'link'\n\t| 'image'\n\t| 'quote'\n\t| 'status'\n\t| 'video'\n\t| 'audio';\n\n/**\n * The REST API context parameter.\n */\nexport type Context = 'view' | 'edit' | 'embed';\n\n/**\n * ContextualField makes the field available only in the specified given contexts,\n * and ensure the field is absent from the object when in a different context.\n *\n * @example\n * ```ts\n * interface Post< C extends Context > {\n * \t…\n * \tmodified: ContextualField< string, 'edit' | 'view', C >;\n * \tpassword: ContextualField< string, 'edit', C >;\n * \t…\n * }\n *\n * const post: Post<'edit'> = …\n * // post.modified exists as a string\n * // post.password exists as a string\n *\n * const post: Post<'view'> = …\n * // post.modified still exists as a string\n * // post.password is missing, undefined, because we're not in the `edit` context.\n * ```\n */\nexport type ContextualField<\n\tFieldType,\n\tAvailableInContexts extends Context,\n\tC extends Context,\n> = AvailableInContexts extends C ? FieldType : never;\n\n/**\n * Removes all the properties of type never, even the deeply nested ones.\n *\n * @example\n * ```ts\n * type MyType = {\n * foo: string;\n * bar: never;\n * nested: {\n * foo: string;\n * bar: never;\n * }\n * }\n * const x = {} as OmitNevers<MyType>;\n * // x is of type { foo: string; nested: { foo: string; }}\n * // The `never` properties were removed entirely\n * ```\n */\nexport type OmitNevers<\n\tT,\n\tNevers = {\n\t\t[ K in keyof T ]: Exclude< T[ K ], undefined > extends never\n\t\t\t? never\n\t\t\t: T[ K ] extends Record< string, unknown >\n\t\t\t? OmitNevers< T[ K ] >\n\t\t\t: T[ K ];\n\t},\n> = Pick<\n\tNevers,\n\t{\n\t\t[ K in keyof Nevers ]: Nevers[ K ] extends never ? never : K;\n\t}[ keyof Nevers ]\n>;\n\n/**\n * A string that the server renders which often involves\n * modifications from the raw source string.\n *\n * For example, block HTML with the comment delimiters exists\n * in `post_content` but those comments are stripped out when\n * rendering to a page view. Similarly, plugins might modify\n * content or replace shortcodes.\n */\nexport interface RenderedText< C extends Context > {\n\t/**\n\t * The source string which will be rendered on page views.\n\t */\n\traw: ContextualField< string, 'edit', C >;\n\t/**\n\t * The output of the raw source after processing and filtering on the server.\n\t */\n\trendered: string;\n}\n\n/**\n * Updatable<EntityRecord> is a type describing Edited Entity Records. They are like\n * regular Entity Records, but they have all the local edits applied on top of the REST API data.\n *\n * This turns certain field from an object into a string.\n *\n * Entities like Post have fields that only be rendered on the server, like title, excerpt,\n * and content. The REST API exposes both the raw markup and the rendered version of those fields.\n * For example, in the block editor, content.rendered could used as a visual preview, and\n * content.raw could be used to populate the code editor.\n *\n * When updating these rendered fields, JavaScript is not be able to properly render arbitrary block\n * markup. Therefore, it stores only the raw markup without the rendered part. And since that's a string,\n * the entire field becomes a string.\n *\n * @example\n * ```ts\n * type Post< C extends Context > {\n * title: RenderedText< C >;\n * }\n * const post = {} as Post;\n * // post.title is an object with raw and rendered properties\n *\n * const updatablePost = {} as Updatable< Post >;\n * // updatablePost.title is a string\n * ```\n */\nexport type Updatable< T extends EntityRecord< 'edit' > > = {\n\t[ K in keyof T ]: T[ K ] extends RenderedText< any > ? string : T[ K ];\n};\n"],"mappings":"","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["@wordpress/core-data/src/entity-types/plugin.ts"],"sourcesContent":["/**\n * Internal dependencies\n */\nimport type {\n\tContext,\n\tContextualField,\n\tRenderedText,\n\tOmitNevers,\n} from './helpers';\n\nimport type { BaseEntityRecords as _BaseEntityRecords } from './base-entity-records';\n\ndeclare module './base-entity-records' {\n\texport namespace BaseEntityRecords {\n\t\texport interface Plugin< C extends Context > {\n\t\t\t/**\n\t\t\t * The plugin file.\n\t\t\t */\n\t\t\tplugin: string;\n\t\t\t/**\n\t\t\t * The plugin activation status.\n\t\t\t */\n\t\t\tstatus: PluginStatus;\n\t\t\t/**\n\t\t\t * The plugin name.\n\t\t\t */\n\t\t\tname: string;\n\t\t\t/**\n\t\t\t * The plugin's website address.\n\t\t\t */\n\t\t\tplugin_uri: ContextualField< string, 'view' | 'edit', C >;\n\t\t\t/**\n\t\t\t * The plugin author.\n\t\t\t */\n\t\t\tauthor: ContextualField<\n\t\t\t\tRecord< string, string >,\n\t\t\t\t'view' | 'edit',\n\t\t\t\tC\n\t\t\t>;\n\t\t\t/**\n\t\t\t * Plugin author's website address.\n\t\t\t */\n\t\t\tauthor_uri: ContextualField< string, 'view' | 'edit', C >;\n\t\t\t/**\n\t\t\t * The plugin description.\n\t\t\t */\n\t\t\tdescription: ContextualField<\n\t\t\t\tRenderedText< 'edit' >,\n\t\t\t\t'view' | 'edit',\n\t\t\t\tC\n\t\t\t>;\n\t\t\t/**\n\t\t\t * The plugin version number.\n\t\t\t */\n\t\t\tversion: ContextualField< string, 'view' | 'edit', C >;\n\t\t\t/**\n\t\t\t * Whether the plugin can only be activated network-wide.\n\t\t\t */\n\t\t\tnetwork_only: boolean;\n\t\t\t/**\n\t\t\t * Minimum required version of WordPress.\n\t\t\t */\n\t\t\trequires_wp: string;\n\t\t\t/**\n\t\t\t * Minimum required version of PHP.\n\t\t\t */\n\t\t\trequires_php: string;\n\t\t\t/**\n\t\t\t * The plugin's text domain.\n\t\t\t */\n\t\t\ttextdomain: ContextualField< string, 'view' | 'edit', C >;\n\t\t}\n\t}\n}\n\nexport type PluginStatus = 'active' | 'inactive';\nexport type Plugin< C extends Context = 'edit' > = OmitNevers<\n\t_BaseEntityRecords.Plugin< C >\n>;\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["@wordpress/core-data/src/entity-types/plugin.ts"],"sourcesContent":["/**\n * Internal dependencies\n */\nimport type {\n\tContext,\n\tContextualField,\n\tRenderedText,\n\tOmitNevers,\n} from './helpers';\n\nimport type { BaseEntityRecords as _BaseEntityRecords } from './base-entity-records';\n\ndeclare module './base-entity-records' {\n\texport namespace BaseEntityRecords {\n\t\texport interface Plugin< C extends Context > {\n\t\t\t/**\n\t\t\t * The plugin file.\n\t\t\t */\n\t\t\tplugin: string;\n\t\t\t/**\n\t\t\t * The plugin activation status.\n\t\t\t */\n\t\t\tstatus: PluginStatus;\n\t\t\t/**\n\t\t\t * The plugin name.\n\t\t\t */\n\t\t\tname: string;\n\t\t\t/**\n\t\t\t * The plugin's website address.\n\t\t\t */\n\t\t\tplugin_uri: ContextualField< string, 'view' | 'edit', C >;\n\t\t\t/**\n\t\t\t * The plugin author.\n\t\t\t */\n\t\t\tauthor: ContextualField<\n\t\t\t\tRecord< string, string >,\n\t\t\t\t'view' | 'edit',\n\t\t\t\tC\n\t\t\t>;\n\t\t\t/**\n\t\t\t * Plugin author's website address.\n\t\t\t */\n\t\t\tauthor_uri: ContextualField< string, 'view' | 'edit', C >;\n\t\t\t/**\n\t\t\t * The plugin description.\n\t\t\t */\n\t\t\tdescription: ContextualField<\n\t\t\t\tRenderedText< 'edit' >,\n\t\t\t\t'view' | 'edit',\n\t\t\t\tC\n\t\t\t>;\n\t\t\t/**\n\t\t\t * The plugin version number.\n\t\t\t */\n\t\t\tversion: ContextualField< string, 'view' | 'edit', C >;\n\t\t\t/**\n\t\t\t * Whether the plugin can only be activated network-wide.\n\t\t\t */\n\t\t\tnetwork_only: boolean;\n\t\t\t/**\n\t\t\t * Minimum required version of WordPress.\n\t\t\t */\n\t\t\trequires_wp: string;\n\t\t\t/**\n\t\t\t * Minimum required version of PHP.\n\t\t\t */\n\t\t\trequires_php: string;\n\t\t\t/**\n\t\t\t * The plugin's text domain.\n\t\t\t */\n\t\t\ttextdomain: ContextualField< string, 'view' | 'edit', C >;\n\t\t}\n\t}\n}\n\nexport type PluginStatus = 'active' | 'inactive' | 'network-active';\nexport type Plugin< C extends Context = 'edit' > = OmitNevers<\n\t_BaseEntityRecords.Plugin< C >\n>;\n"],"mappings":"","ignoreList":[]}