This is an automated email from the ASF dual-hosted git repository.
jeffreyh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris-website.git
The following commit(s) were added to refs/heads/master by this push:
new 99e243aefc1 fix:change searchbar version to 0.45 (#1468)
99e243aefc1 is described below
commit 99e243aefc1586b37d5c0f82e96762b279e6388c
Author: yangon <[email protected]>
AuthorDate: Fri Dec 6 12:29:37 2024 +0800
fix:change searchbar version to 0.45 (#1468)
Co-authored-by: liyang <[email protected]>
---
package.json | 4 +-
src/theme/SearchBar/SearchBar.jsx | 362 ++++++++++++++++++-------------
src/theme/SearchBar/SearchBar.module.css | 9 +
src/theme/SearchBar/fetchIndexes.js | 20 +-
src/theme/SearchBar/searchByWorker.js | 25 ---
yarn.lock | 8 +-
6 files changed, 243 insertions(+), 185 deletions(-)
diff --git a/package.json b/package.json
index b440ea0c3f3..3a73b791062 100644
--- a/package.json
+++ b/package.json
@@ -24,12 +24,11 @@
"@docusaurus/plugin-client-redirects": "3.6.3",
"@docusaurus/plugin-pwa": "3.6.3",
"@docusaurus/preset-classic": "3.6.3",
- "@easyops-cn/docusaurus-search-local": "0.30.2",
+ "@easyops-cn/docusaurus-search-local": "0.45",
"@mdx-js/react": "^3.0.0",
"antd": "^5.12.2",
"autoprefixer": "^10.4.16",
"clsx": "^1.1.1",
- "remote-web-worker": "0.0.9",
"copy-to-clipboard": "^3.3.3",
"docusaurus-plugin-matomo": "^0.0.8",
"docusaurus-plugin-sass": "^0.2.3",
@@ -38,6 +37,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-github-button": "^0.1.11",
+ "remote-web-worker": "0.0.9",
"sass": "^1.63.2",
"sass-migrator": "^2.2.1",
"swiper": "^9.0.5",
diff --git a/src/theme/SearchBar/SearchBar.jsx
b/src/theme/SearchBar/SearchBar.jsx
index 14154b5a238..bb972bf88b9 100644
--- a/src/theme/SearchBar/SearchBar.jsx
+++ b/src/theme/SearchBar/SearchBar.jsx
@@ -1,42 +1,36 @@
-import React, { useCallback, useEffect, useRef, useState } from 'react';
-import clsx from 'clsx';
-import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
-import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
-import { useHistory, useLocation } from '@docusaurus/router';
-import { translate } from '@docusaurus/Translate';
-import { ReactContextError, useDocsPreferredVersion } from
'@docusaurus/theme-common';
-import { useActivePlugin } from '@docusaurus/plugin-content-docs/client';
-import { fetchIndexes } from './fetchIndexes';
-import { SearchSourceFactory } from '../../utils/SearchSourceFactory';
-import { SuggestionTemplate } from './SuggestionTemplate';
-import { EmptyTemplate } from './EmptyTemplate';
-import {
- searchResultLimits,
- Mark,
- searchBarShortcut,
- searchBarShortcutHint,
- docsPluginIdForPreferredVersion,
- indexDocs,
-} from '../../utils/proxiedGenerated';
-import LoadingRing from '../LoadingRing/LoadingRing';
-import styles from './SearchBar.module.css';
+import React, { useCallback, useEffect, useRef, useState, } from "react";
+import clsx from "clsx";
+import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
+import useIsBrowser from "@docusaurus/useIsBrowser";
+import { useHistory, useLocation } from "@docusaurus/router";
+import { translate } from "@docusaurus/Translate";
+import { ReactContextError, useDocsPreferredVersion, } from
"@docusaurus/theme-common";
+import { useActivePlugin } from "@docusaurus/plugin-content-docs/client";
+import { fetchIndexes } from "./fetchIndexes";
+import { SearchSourceFactory } from "../../utils/SearchSourceFactory";
+import { SuggestionTemplate } from "./SuggestionTemplate";
+import { EmptyTemplate } from "./EmptyTemplate";
+import { searchResultLimits, Mark, searchBarShortcut, searchBarShortcutHint,
searchBarPosition, docsPluginIdForPreferredVersion, indexDocs,
searchContextByPaths, hideSearchBarWithNoSearchContext,
useAllContextsWithNoSearchContext, } from "../../utils/proxiedGenerated";
+import LoadingRing from "../LoadingRing/LoadingRing";
+import styles from "./SearchBar.module.css";
+import { normalizeContextByPath } from "../../utils/normalizeContextByPath";
async function fetchAutoCompleteJS() {
- const autoCompleteModule = await import('@easyops-cn/autocomplete.js');
+ const autoCompleteModule = await import("@easyops-cn/autocomplete.js");
const autoComplete = autoCompleteModule.default;
if (autoComplete.noConflict) {
// For webpack v5 since docusaurus v2.0.0-alpha.75
autoComplete.noConflict();
- } else if (autoCompleteModule.noConflict) {
+ }
+ else if (autoCompleteModule.noConflict) {
// For webpack v4 before docusaurus v2.0.0-alpha.74
autoCompleteModule.noConflict();
}
return autoComplete;
}
-const SEARCH_PARAM_HIGHLIGHT = '_highlight';
-export default function SearchBar({ handleSearchBarToggle }) {
- const {
- siteConfig: { baseUrl },
- } = useDocusaurusContext();
+const SEARCH_PARAM_HIGHLIGHT = "_highlight";
+export default function SearchBar({ handleSearchBarToggle, }) {
+ const isBrowser = useIsBrowser();
+ const { siteConfig: { baseUrl }, i18n: { currentLocale }, } =
useDocusaurusContext();
// It returns undefined for non-docs pages
const activePlugin = useActivePlugin();
let versionUrl = baseUrl;
@@ -51,13 +45,15 @@ export default function SearchBar({ handleSearchBarToggle
}) {
// eslint-disable-next-line react-hooks/rules-of-hooks
const { preferredVersion } =
useDocsPreferredVersion(activePlugin?.pluginId ??
docsPluginIdForPreferredVersion);
if (preferredVersion && !preferredVersion.isLast) {
- versionUrl = preferredVersion.path + '/';
+ versionUrl = preferredVersion.path + "/";
}
- } catch (e) {
+ }
+ catch (e) {
if (indexDocs) {
if (e instanceof ReactContextError) {
/* ignore, happens when website doesn't use versions */
- } else {
+ }
+ else {
throw e;
}
}
@@ -70,90 +66,164 @@ export default function SearchBar({ handleSearchBarToggle
}) {
const focusAfterIndexLoaded = useRef(false);
const [loading, setLoading] = useState(false);
const [inputChanged, setInputChanged] = useState(false);
- const [inputValue, setInputValue] = useState('');
+ const [inputValue, setInputValue] = useState("");
const search = useRef(null);
+ const prevSearchContext = useRef("");
+ const [searchContext, setSearchContext] = useState("");
+ useEffect(() => {
+ if (!Array.isArray(searchContextByPaths)) {
+ return;
+ }
+ let nextSearchContext = "";
+ if (location.pathname.startsWith(versionUrl)) {
+ const uri = location.pathname.substring(versionUrl.length);
+ let matchedPath;
+ for (const _path of searchContextByPaths) {
+ const path = typeof _path === "string" ? _path : _path.path;
+ if (uri === path || uri.startsWith(`${path}/`)) {
+ matchedPath = path;
+ break;
+ }
+ }
+ if (matchedPath) {
+ nextSearchContext = matchedPath;
+ }
+ }
+ if (prevSearchContext.current !== nextSearchContext) {
+ // Reset index state map once search context is changed.
+ indexStateMap.current.delete(nextSearchContext);
+ prevSearchContext.current = nextSearchContext;
+ }
+ setSearchContext(nextSearchContext);
+ }, [location.pathname, versionUrl]);
+ const hidden = !!hideSearchBarWithNoSearchContext &&
+ Array.isArray(searchContextByPaths) &&
+ searchContext === "";
const loadIndex = useCallback(async () => {
- if (indexState.current !== 'empty') {
+ if (hidden || indexStateMap.current.get(searchContext)) {
// Do not load the index (again) if its already loaded or in the
process of being loaded.
return;
}
- indexState.current = 'loading';
+ indexStateMap.current.set(searchContext, "loading");
+ search.current?.autocomplete.destroy();
setLoading(true);
const [{ wrappedIndexes, zhDictionary }, autoComplete] = await
Promise.all([
- fetchIndexes(versionUrl),
+ fetchIndexes(versionUrl, searchContext),
fetchAutoCompleteJS(),
]);
- search.current = autoComplete(
- searchBarRef.current,
- {
- hint: false,
- autoselect: true,
- openOnFocus: true,
- cssClasses: {
- root: styles.searchBar,
- noPrefix: true,
- dropdownMenu: styles.dropdownMenu,
- input: styles.input,
- hint: styles.hint,
- suggestions: styles.suggestions,
- suggestion: styles.suggestion,
- cursor: styles.cursor,
- dataset: styles.dataset,
- empty: styles.empty,
- },
+ const searchFooterLinkElement = ({ query, isEmpty, }) => {
+ const a = document.createElement("a");
+ const params = new URLSearchParams();
+ params.set("q", query);
+ let linkText;
+ if (searchContext) {
+ const detailedSearchContext = searchContext &&
Array.isArray(searchContextByPaths)
+ ? searchContextByPaths.find((item) => typeof item ===
"string"
+ ? item === searchContext
+ : item.path === searchContext)
+ : searchContext;
+ const translatedSearchContext = detailedSearchContext
+ ? normalizeContextByPath(detailedSearchContext,
currentLocale).label
+ : searchContext;
+ if (useAllContextsWithNoSearchContext && isEmpty) {
+ linkText = translate({
+ id: "theme.SearchBar.seeAllOutsideContext",
+ message: 'See all results outside "{context}"',
+ }, { context: translatedSearchContext });
+ }
+ else {
+ linkText = translate({
+ id: "theme.SearchBar.searchInContext",
+ message: 'See all results within "{context}"',
+ }, { context: translatedSearchContext });
+ }
+ }
+ else {
+ linkText = translate({
+ id: "theme.SearchBar.seeAll",
+ message: "See all results",
+ });
+ }
+ if (searchContext &&
+ Array.isArray(searchContextByPaths) &&
+ (!useAllContextsWithNoSearchContext || !isEmpty)) {
+ params.set("ctx", searchContext);
+ }
+ if (versionUrl !== baseUrl) {
+ if (!versionUrl.startsWith(baseUrl)) {
+ throw new Error(`Version url '${versionUrl}' does not
start with base url '${baseUrl}', this is a bug of
\`@easyops-cn/docusaurus-search-local\`, please report it.`);
+ }
+ params.set("version", versionUrl.substring(baseUrl.length));
+ }
+ const url = `${baseUrl}search/?${params.toString()}`;
+ a.href = url;
+ a.textContent = linkText;
+ a.addEventListener("click", (e) => {
+ if (!e.ctrlKey && !e.metaKey) {
+ e.preventDefault();
+ search.current?.autocomplete.close();
+ history.push(url);
+ }
+ });
+ return a;
+ };
+ search.current = autoComplete(searchBarRef.current, {
+ hint: false,
+ autoselect: true,
+ openOnFocus: true,
+ cssClasses: {
+ root: clsx(styles.searchBar, {
+ [styles.searchBarLeft]: searchBarPosition === "left",
+ }),
+ noPrefix: true,
+ dropdownMenu: styles.dropdownMenu,
+ input: styles.input,
+ hint: styles.hint,
+ suggestions: styles.suggestions,
+ suggestion: styles.suggestion,
+ cursor: styles.cursor,
+ dataset: styles.dataset,
+ empty: styles.empty,
},
- [
- {
- source: SearchSourceFactory(wrappedIndexes, zhDictionary,
searchResultLimits),
- templates: {
- suggestion: SuggestionTemplate,
- empty: EmptyTemplate,
- footer: ({ query, isEmpty }) => {
- if (isEmpty) {
- return;
- }
- const a = document.createElement('a');
- const url =
`${baseUrl}search?q=${encodeURIComponent(query)}`;
- a.href = url;
- a.textContent = translate({
- id: 'theme.SearchBar.seeAll',
- message: 'See all results',
- });
- a.addEventListener('click', e => {
- if (!e.ctrlKey && !e.metaKey) {
- e.preventDefault();
- search.current.autocomplete.close();
- history.push(url);
- }
- });
- const div = document.createElement('div');
- div.className = styles.hitFooter;
- div.appendChild(a);
- return div;
- },
+ }, [
+ {
+ source: SearchSourceFactory(wrappedIndexes, zhDictionary,
searchResultLimits),
+ templates: {
+ suggestion: SuggestionTemplate,
+ empty: EmptyTemplate,
+ footer: ({ query, isEmpty }) => {
+ if (isEmpty &&
+ (!searchContext ||
!useAllContextsWithNoSearchContext)) {
+ return;
+ }
+ const a = searchFooterLinkElement({ query, isEmpty });
+ const div = document.createElement("div");
+ div.className = styles.hitFooter;
+ div.appendChild(a);
+ return div;
},
},
- ],
- )
- .on('autocomplete:selected', function (event, { document: { u, h
}, tokens }) {
- searchBarRef.current?.blur();
- let url = u;
- if (Mark && tokens.length > 0) {
- const params = new URLSearchParams();
- for (const token of tokens) {
- params.append(SEARCH_PARAM_HIGHLIGHT, token);
- }
- url += `?${params.toString()}`;
- }
- if (h) {
- url += h;
+ },
+ ])
+ .on("autocomplete:selected", function (event, { document: { u, h
}, tokens }) {
+ searchBarRef.current?.blur();
+ let url = u;
+ if (Mark && tokens.length > 0) {
+ const params = new URLSearchParams();
+ for (const token of tokens) {
+ params.append(SEARCH_PARAM_HIGHLIGHT, token);
}
- history.push(url);
- })
- .on('autocomplete:closed', () => {
- searchBarRef.current?.blur();
- });
- indexState.current = 'done';
+ url += `?${params.toString()}`;
+ }
+ if (h) {
+ url += h;
+ }
+ history.push(url);
+ })
+ .on("autocomplete:closed", () => {
+ searchBarRef.current?.blur();
+ });
+ indexStateMap.current.set(searchContext, "done");
setLoading(false);
if (focusAfterIndexLoaded.current) {
const input = searchBarRef.current;
@@ -167,7 +237,7 @@ export default function SearchBar({ handleSearchBarToggle
}) {
if (!Mark) {
return;
}
- const keywords = ExecutionEnvironment.canUseDOM
+ const keywords = isBrowser
? new
URLSearchParams(location.search).getAll(SEARCH_PARAM_HIGHLIGHT)
: [];
// A workaround to fix an issue of highlighting in code blocks.
@@ -175,7 +245,7 @@ export default function SearchBar({ handleSearchBarToggle
}) {
// Code blocks will be re-rendered after this `useEffect` ran.
// So we make the marking run after a macro task.
setTimeout(() => {
- const root = document.querySelector('article');
+ const root = document.querySelector("article");
if (!root) {
return;
}
@@ -185,8 +255,8 @@ export default function SearchBar({ handleSearchBarToggle
}) {
mark.mark(keywords);
}
// Apply any keywords to the search input so that we can clear
marks in case we loaded a page with a highlight in the url
- setInputValue(keywords.join(' '));
- search.current?.autocomplete.setVal(keywords.join(' '));
+ setInputValue(keywords.join(" "));
+ search.current?.autocomplete.setVal(keywords.join(" "));
});
}, [location.search, location.pathname]);
const [focused, setFocused] = useState(false);
@@ -203,14 +273,14 @@ export default function SearchBar({ handleSearchBarToggle
}) {
const onInputMouseEnter = useCallback(() => {
loadIndex();
}, [loadIndex]);
- const onInputChange = useCallback(event => {
+ const onInputChange = useCallback((event) => {
setInputValue(event.target.value);
if (event.target.value) {
setInputChanged(true);
}
}, []);
// Implement hint icons for the search shortcuts on mac and the rest
operating systems.
- const isMac = ExecutionEnvironment.canUseDOM
+ const isMac = isBrowser
? /mac/i.test(navigator.userAgentData?.platform ?? navigator.platform)
: false;
useEffect(() => {
@@ -218,64 +288,52 @@ export default function SearchBar({ handleSearchBarToggle
}) {
return;
}
// Add shortcuts command/ctrl + K
- const handleShortcut = event => {
- if ((isMac ? event.metaKey : event.ctrlKey) && event.code ===
'KeyK') {
+ const handleShortcut = (event) => {
+ if ((isMac ? event.metaKey : event.ctrlKey) &&
+ (event.key === "k" || event.key === "K")) {
event.preventDefault();
searchBarRef.current?.focus();
onInputFocus();
}
};
- document.addEventListener('keydown', handleShortcut);
+ document.addEventListener("keydown", handleShortcut);
return () => {
- document.removeEventListener('keydown', handleShortcut);
+ document.removeEventListener("keydown", handleShortcut);
};
}, [isMac, onInputFocus]);
const onClearSearch = useCallback(() => {
const params = new URLSearchParams(location.search);
params.delete(SEARCH_PARAM_HIGHLIGHT);
const paramsStr = params.toString();
- const searchUrl = location.pathname + (paramsStr != '' ?
`?${paramsStr}` : '') + location.hash;
+ const searchUrl = location.pathname +
+ (paramsStr != "" ? `?${paramsStr}` : "") +
+ location.hash;
if (searchUrl != location.pathname + location.search + location.hash) {
history.push(searchUrl);
}
// We always clear these here because in case no match was selected
the above history push wont happen
- setInputValue('');
- search.current?.autocomplete.setVal('');
+ setInputValue("");
+ search.current?.autocomplete.setVal("");
}, [location.pathname, location.search, location.hash, history]);
- return (
- <div
- className={clsx('navbar__search', styles.searchBarContainer, {
- [styles.searchIndexLoading]: loading && inputChanged,
- [styles.focused]: focused,
- })}
- >
- <input
- placeholder={translate({
- id: 'theme.SearchBar.label',
- message: 'Search',
- description: 'The ARIA label and placeholder for search
button',
- })}
- aria-label="Search"
- className={clsx('navbar__search-input',
styles.navbarSearchInput)}
- onMouseEnter={onInputMouseEnter}
- onFocus={onInputFocus}
- onBlur={onInputBlur}
- onChange={onInputChange}
- ref={searchBarRef}
- value={inputValue}
- />
- <LoadingRing className={styles.searchBarLoadingRing} />
- {searchBarShortcut &&
- (inputValue !== '' ? (
- <button className={styles.searchClearButton}
onClick={onClearSearch}>
- ✕
- </button>
- ) : (
- <div className={styles.searchHintContainer}>
- <kbd className={styles.searchHint}>{isMac ? '⌘' :
'ctrl'}</kbd>
- <kbd className={styles.searchHint}>K</kbd>
- </div>
- ))}
- </div>
- );
+ return (<div className={clsx("navbar__search", styles.searchBarContainer, {
+ [styles.searchIndexLoading]: loading && inputChanged,
+ [styles.focused]: focused,
+ })} hidden={hidden}
+ // Manually make the search bar be LTR even if in RTL
+ dir="ltr">
+ <input placeholder={translate({
+ id: "theme.SearchBar.label",
+ message: "Search",
+ description: "The ARIA label and placeholder for search button",
+ })} aria-label="Search" className="navbar__search-input"
onMouseEnter={onInputMouseEnter} onFocus={onInputFocus} onBlur={onInputBlur}
onChange={onInputChange} ref={searchBarRef} value={inputValue}/>
+ <LoadingRing className={styles.searchBarLoadingRing}/>
+ {searchBarShortcut &&
+ searchBarShortcutHint &&
+ (inputValue !== "" ? (<button className={styles.searchClearButton}
onClick={onClearSearch}>
+ ✕
+ </button>) : (isBrowser && (<div
className={styles.searchHintContainer}>
+ <kbd className={styles.searchHint}>{isMac ? "⌘" : "ctrl"}</kbd>
+ <kbd className={styles.searchHint}>K</kbd>
+ </div>)))}
+ </div>);
}
diff --git a/src/theme/SearchBar/SearchBar.module.css
b/src/theme/SearchBar/SearchBar.module.css
index 1777c864ed6..a3e2c1d6d8f 100644
--- a/src/theme/SearchBar/SearchBar.module.css
+++ b/src/theme/SearchBar/SearchBar.module.css
@@ -16,6 +16,13 @@
padding: var(--search-local-spacing, 12px);
}
+@media not (max-width: 996px) {
+ .searchBar.searchBarLeft .dropdownMenu {
+ left: 0 !important;
+ right: auto !important;
+ }
+}
+
@media (max-width: 576px) {
:global(.navbar__search-input):not(:focus) {
width: 2rem;
@@ -248,6 +255,8 @@ html[data-theme="dark"] .noResultsIcon {
.hint {
}
.suggestions {
+ max-height: 500px !important;
+ overflow: scroll !important;
}
.dataset {
}
diff --git a/src/theme/SearchBar/fetchIndexes.js
b/src/theme/SearchBar/fetchIndexes.js
index 2c6113c7cb5..51e15458214 100644
--- a/src/theme/SearchBar/fetchIndexes.js
+++ b/src/theme/SearchBar/fetchIndexes.js
@@ -1,8 +1,24 @@
import lunr from "lunr";
import { searchIndexUrl } from "../../utils/proxiedGenerated";
-export async function fetchIndexes(baseUrl) {
+const cache = new Map();
+export function fetchIndexes(baseUrl, searchContext) {
+ const cacheKey = `${baseUrl}${searchContext}`;
+ let promise = cache.get(cacheKey);
+ if (!promise) {
+ promise = legacyFetchIndexes(baseUrl, searchContext);
+ cache.set(cacheKey, promise);
+ }
+ return promise;
+}
+export async function legacyFetchIndexes(baseUrl, searchContext) {
if (process.env.NODE_ENV === "production") {
- const json = (await (await
fetch(`${baseUrl}${searchIndexUrl}`)).json());
+ const url = `${baseUrl}${searchIndexUrl.replace("{dir}", searchContext
? `-${searchContext.replace(/\//g, "-")}` : "")}`;
+ // Catch potential attacks.
+ const fullUrl = new URL(url, location.origin);
+ if (fullUrl.origin !== location.origin) {
+ throw new Error("Unexpected version url");
+ }
+ const json = (await (await fetch(url)).json());
const wrappedIndexes = json.map(({ documents, index }, type) => ({
type: type,
documents,
diff --git a/src/theme/SearchBar/searchByWorker.js
b/src/theme/SearchBar/searchByWorker.js
deleted file mode 100644
index 13ab2bdaca7..00000000000
--- a/src/theme/SearchBar/searchByWorker.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import 'remote-web-worker';
-import * as Comlink from "comlink";
-let remoteWorkerPromise;
-function getRemoteWorker() {
- if (process.env.NODE_ENV === "production" && !remoteWorkerPromise) {
- remoteWorkerPromise = (async () => {
- const Remote = Comlink.wrap(new Worker(new URL("./worker.js",
import.meta.url), { type: 'classic' }));
- return await new Remote();
- })();
- }
- return remoteWorkerPromise;
-}
-export async function fetchIndexesByWorker(baseUrl, searchContext) {
- if (process.env.NODE_ENV === "production") {
- const remoteWorker = await getRemoteWorker();
- await remoteWorker.fetchIndexes(baseUrl, searchContext);
- }
-}
-export async function searchByWorker(baseUrl, searchContext, input) {
- if (process.env.NODE_ENV === "production") {
- const remoteWorker = await getRemoteWorker();
- return remoteWorker.search(baseUrl, searchContext, input);
- }
- return [];
-}
diff --git a/yarn.lock b/yarn.lock
index b10ecc6fbba..dc17c972bb2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2434,10 +2434,10 @@
cssesc "^3.0.0"
immediate "^3.2.3"
-"@easyops-cn/[email protected]":
- version "0.30.2"
- resolved
"https://registry.npmmirror.com/@easyops-cn/docusaurus-search-local/-/docusaurus-search-local-0.30.2.tgz#41d0813ff4ece58fe38d8ace35f0187036c95d92"
- integrity
sha512-q2tYUuNjUbsSxv3vB04ItP/jp0teWswXtsLxNF6JgaDOHkNXEjQFmbaOoBLyIcPCawefxC0m/iZibzr1JAVGew==
+"@easyops-cn/[email protected]":
+ version "0.45.0"
+ resolved
"https://registry.npmmirror.com/@easyops-cn/docusaurus-search-local/-/docusaurus-search-local-0.45.0.tgz#7101d59c9359b50b1add306d2504a09bd7176adb"
+ integrity
sha512-ccJjeYmBHrv2v8Y9eQnH79S0PEKcogACKkEatEKPcad7usQj/14jA9POUUUYW/yougLSXghwe+uIncbuUBuBFg==
dependencies:
"@docusaurus/plugin-content-docs" "^2.0.0-rc.1"
"@docusaurus/theme-translations" "^2.0.0-rc.1"
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]