UNPKG

@wordpress/core-data

Version:
154 lines (153 loc) 4.67 kB
// packages/core-data/src/fetch/__experimental-fetch-link-suggestions.ts import apiFetch from "@wordpress/api-fetch"; import { addQueryArgs } from "@wordpress/url"; import { decodeEntities } from "@wordpress/html-entities"; import { __ } from "@wordpress/i18n"; async function fetchLinkSuggestions(search, searchOptions = {}, editorSettings = {}) { const searchOptionsToUse = searchOptions.isInitialSuggestions && searchOptions.initialSuggestionsSearchOptions ? { ...searchOptions, ...searchOptions.initialSuggestionsSearchOptions } : searchOptions; const { type, subtype, page, perPage = searchOptions.isInitialSuggestions ? 3 : 20 } = searchOptionsToUse; const { disablePostFormats = false } = editorSettings; const queries = []; if (!type || type === "post") { queries.push( apiFetch({ path: addQueryArgs("/wp/v2/search", { search, page, per_page: perPage, type: "post", subtype }) }).then((results2) => { return results2.map((result) => { return { id: result.id, url: result.url, title: decodeEntities(result.title || "") || __("(no title)"), type: result.subtype || result.type, kind: "post-type" }; }); }).catch(() => []) // Fail by returning no results. ); } if (!type || type === "term") { queries.push( apiFetch({ path: addQueryArgs("/wp/v2/search", { search, page, per_page: perPage, type: "term", subtype }) }).then((results2) => { return results2.map((result) => { return { id: result.id, url: result.url, title: decodeEntities(result.title || "") || __("(no title)"), type: result.subtype || result.type, kind: "taxonomy" }; }); }).catch(() => []) // Fail by returning no results. ); } if (!disablePostFormats && (!type || type === "post-format")) { queries.push( apiFetch({ path: addQueryArgs("/wp/v2/search", { search, page, per_page: perPage, type: "post-format", subtype }) }).then((results2) => { return results2.map((result) => { return { id: result.id, url: result.url, title: decodeEntities(result.title || "") || __("(no title)"), type: result.subtype || result.type, kind: "taxonomy" }; }); }).catch(() => []) // Fail by returning no results. ); } if (!type || type === "attachment") { queries.push( apiFetch({ path: addQueryArgs("/wp/v2/media", { search, page, per_page: perPage }) }).then((results2) => { return results2.map((result) => { return { id: result.id, url: result.source_url, title: decodeEntities(result.title.rendered || "") || __("(no title)"), type: result.type, kind: "media" }; }); }).catch(() => []) // Fail by returning no results. ); } const responses = await Promise.all(queries); let results = responses.flat(); results = results.filter((result) => !!result.id); results = sortResults(results, search); results = results.slice(0, perPage); return results; } function sortResults(results, search) { const searchTokens = tokenize(search); const scores = {}; for (const result of results) { if (result.title) { const titleTokens = tokenize(result.title); const exactMatchingTokens = titleTokens.filter( (titleToken) => searchTokens.some( (searchToken) => titleToken === searchToken ) ); const subMatchingTokens = titleTokens.filter( (titleToken) => searchTokens.some( (searchToken) => titleToken !== searchToken && titleToken.includes(searchToken) ) ); const exactMatchScore = exactMatchingTokens.length / titleTokens.length * 10; const subMatchScore = subMatchingTokens.length / titleTokens.length; scores[result.id] = exactMatchScore + subMatchScore; } else { scores[result.id] = 0; } } return results.sort((a, b) => scores[b.id] - scores[a.id]); } function tokenize(text) { return text.toLowerCase().match(/[\p{L}\p{N}]+/gu) || []; } export { fetchLinkSuggestions as default, sortResults, tokenize }; //# sourceMappingURL=__experimental-fetch-link-suggestions.js.map