@easyops-cn/docusaurus-search-local 0.36.0 → 0.37.2
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 +21 -0
- package/dist/server/index.js +1 -2
- package/dist/server/server/index.js +32 -42
- package/dist/server/server/utils/buildIndex.js +17 -20
- package/dist/server/server/utils/cutWordByUnderscore.js +1 -5
- package/dist/server/server/utils/debug.js +5 -9
- package/dist/server/server/utils/generate.js +6 -11
- package/dist/server/server/utils/getCondensedText.js +1 -5
- package/dist/server/server/utils/getIndexHash.js +14 -19
- package/dist/server/server/utils/parse.js +7 -12
- package/dist/server/server/utils/parseDocument.js +5 -9
- package/dist/server/server/utils/parsePage.js +5 -9
- package/dist/server/server/utils/postBuildFactory.js +62 -69
- package/dist/server/server/utils/processDocInfos.js +9 -14
- package/dist/server/server/utils/processPluginOptions.js +6 -12
- package/dist/server/server/utils/scanDocuments.js +44 -51
- package/dist/server/server/utils/tokenizer.js +26 -20
- package/dist/server/server/utils/validateOptions.js +24 -28
- package/dist/server/shared/generateTrimmer.js +1 -5
- package/dist/server/shared/interfaces.js +1 -2
- package/dist/server/shared/lunrLanguageZh.js +3 -7
- package/package.json +16 -16
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [0.37.2](https://github.com/easyops-cn/docusaurus-search-local/compare/v0.37.1...v0.37.2) (2023-11-09)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* support both Docusaurus v2 and v3 ([89bd0f5](https://github.com/easyops-cn/docusaurus-search-local/commit/89bd0f5e7478b9b22e40a5df5efcfd0ed2082a74))
|
|
11
|
+
|
|
12
|
+
## [0.37.1](https://github.com/easyops-cn/docusaurus-search-local/compare/v0.37.0...v0.37.1) (2023-11-09)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* update readme and fix release workflow ([e11ad12](https://github.com/easyops-cn/docusaurus-search-local/commit/e11ad1287958e22a16da9309b4070433507233d9))
|
|
18
|
+
|
|
19
|
+
## [0.37.0](https://github.com/easyops-cn/docusaurus-search-local/compare/v0.36.0...v0.37.0) (2023-11-09)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
|
|
24
|
+
* support docusaurus v3 ([18c01c2](https://github.com/easyops-cn/docusaurus-search-local/commit/18c01c2f52ccee9c7d4b7307c4c465b7190c26a7))
|
|
25
|
+
|
|
5
26
|
## [0.36.0](https://github.com/easyops-cn/docusaurus-search-local/compare/v0.35.0...v0.36.0) (2023-09-09)
|
|
6
27
|
|
|
7
28
|
|
package/dist/server/index.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,57 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const theme_translations_1 = require("@docusaurus/theme-translations");
|
|
9
|
-
const processPluginOptions_1 = require("./utils/processPluginOptions");
|
|
10
|
-
const postBuildFactory_1 = require("./utils/postBuildFactory");
|
|
11
|
-
const generate_1 = require("./utils/generate");
|
|
1
|
+
import path from "path";
|
|
2
|
+
import fs from "fs-extra";
|
|
3
|
+
import { normalizeUrl } from "@docusaurus/utils";
|
|
4
|
+
import { codeTranslationLocalesToTry } from "@docusaurus/theme-translations";
|
|
5
|
+
import { processPluginOptions } from "./utils/processPluginOptions";
|
|
6
|
+
import { postBuildFactory } from "./utils/postBuildFactory";
|
|
7
|
+
import { generate } from "./utils/generate";
|
|
12
8
|
const PLUGIN_NAME = "@easyops-cn/docusaurus-search-local";
|
|
13
|
-
function DocusaurusSearchLocalPlugin(context, options) {
|
|
14
|
-
const config =
|
|
15
|
-
const dir =
|
|
16
|
-
|
|
17
|
-
const searchIndexFilename =
|
|
18
|
-
const themePath =
|
|
19
|
-
const pagePath =
|
|
9
|
+
export default function DocusaurusSearchLocalPlugin(context, options) {
|
|
10
|
+
const config = processPluginOptions(options, context);
|
|
11
|
+
const dir = path.join(context.generatedFilesDir, PLUGIN_NAME, "default");
|
|
12
|
+
fs.ensureDirSync(dir);
|
|
13
|
+
const searchIndexFilename = generate(config, dir);
|
|
14
|
+
const themePath = path.resolve(__dirname, "../../client/client/theme");
|
|
15
|
+
const pagePath = path.join(themePath, "SearchPage/index.js");
|
|
20
16
|
return {
|
|
21
17
|
name: PLUGIN_NAME,
|
|
22
18
|
getThemePath() {
|
|
23
19
|
return themePath;
|
|
24
20
|
},
|
|
25
|
-
postBuild:
|
|
21
|
+
postBuild: postBuildFactory(config, searchIndexFilename),
|
|
26
22
|
getPathsToWatch() {
|
|
27
23
|
return [pagePath];
|
|
28
24
|
},
|
|
29
|
-
getDefaultCodeTranslationMessages() {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return fs_extra_1.default.readJSON(filePath);
|
|
39
|
-
}
|
|
25
|
+
async getDefaultCodeTranslationMessages() {
|
|
26
|
+
const dirPath = path.join(__dirname, "../../locales");
|
|
27
|
+
const localesToTry = codeTranslationLocalesToTry(context.i18n.currentLocale);
|
|
28
|
+
// Return the content of the first file that match
|
|
29
|
+
// fr_FR.json => fr.json => nothing
|
|
30
|
+
for (const locale of localesToTry) {
|
|
31
|
+
const filePath = path.resolve(dirPath, `${locale}.json`);
|
|
32
|
+
if (await fs.pathExists(filePath)) {
|
|
33
|
+
return fs.readJSON(filePath);
|
|
40
34
|
}
|
|
41
|
-
|
|
42
|
-
}
|
|
35
|
+
}
|
|
36
|
+
return {};
|
|
43
37
|
},
|
|
44
|
-
contentLoaded({ actions: { addRoute } }) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
exact: true,
|
|
50
|
-
});
|
|
38
|
+
async contentLoaded({ actions: { addRoute } }) {
|
|
39
|
+
addRoute({
|
|
40
|
+
path: normalizeUrl([context.baseUrl, "search"]),
|
|
41
|
+
component: "@theme/SearchPage",
|
|
42
|
+
exact: true,
|
|
51
43
|
});
|
|
52
44
|
},
|
|
53
45
|
};
|
|
54
46
|
}
|
|
55
|
-
|
|
56
|
-
var validateOptions_1 = require("./utils/validateOptions");
|
|
57
|
-
Object.defineProperty(exports, "validateOptions", { enumerable: true, get: function () { return validateOptions_1.validateOptions; } });
|
|
47
|
+
export { validateOptions } from "./utils/validateOptions";
|
|
@@ -1,57 +1,54 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.buildIndex = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
1
|
/* eslint @typescript-eslint/no-var-requires: 0 */
|
|
6
|
-
|
|
7
|
-
function buildIndex(allDocuments, { language, removeDefaultStopWordFilter, removeDefaultStemmer, zhUserDict, zhUserDictPath, }) {
|
|
2
|
+
import lunr from "lunr";
|
|
3
|
+
export function buildIndex(allDocuments, { language, removeDefaultStopWordFilter, removeDefaultStemmer, zhUserDict, zhUserDictPath, }) {
|
|
8
4
|
if (language.length > 1 || language.some((item) => item !== "en")) {
|
|
9
|
-
require("lunr-languages/lunr.stemmer.support")(
|
|
5
|
+
require("lunr-languages/lunr.stemmer.support")(lunr);
|
|
10
6
|
}
|
|
11
7
|
if (language.includes("ja") || language.includes("jp")) {
|
|
12
|
-
require("lunr-languages/tinyseg")(
|
|
8
|
+
require("lunr-languages/tinyseg")(lunr);
|
|
13
9
|
}
|
|
14
10
|
for (const lang of language.filter((item) => item !== "en" && item !== "zh")) {
|
|
15
|
-
require(`lunr-languages/lunr.${lang}`)(
|
|
11
|
+
require(`lunr-languages/lunr.${lang}`)(lunr);
|
|
16
12
|
}
|
|
17
13
|
if (language.includes("zh")) {
|
|
18
14
|
const { tokenizer, loadUserDict } = require("./tokenizer");
|
|
19
15
|
loadUserDict(zhUserDict, zhUserDictPath);
|
|
20
|
-
require("../../shared/lunrLanguageZh").lunrLanguageZh(
|
|
16
|
+
require("../../shared/lunrLanguageZh").lunrLanguageZh(lunr, tokenizer);
|
|
21
17
|
}
|
|
22
18
|
if (language.length > 1) {
|
|
23
|
-
require("lunr-languages/lunr.multi")(
|
|
19
|
+
require("lunr-languages/lunr.multi")(lunr);
|
|
24
20
|
}
|
|
25
21
|
return allDocuments.map((documents) => ({
|
|
26
22
|
documents,
|
|
27
|
-
index: (
|
|
23
|
+
index: lunr(function () {
|
|
28
24
|
if (language.length > 1) {
|
|
29
|
-
this.use(
|
|
25
|
+
this.use(lunr.multiLanguage(...language));
|
|
30
26
|
}
|
|
31
27
|
else if (language[0] !== "en") {
|
|
32
|
-
this.use(
|
|
28
|
+
this.use(lunr[language[0]]);
|
|
33
29
|
}
|
|
34
30
|
if (removeDefaultStopWordFilter) {
|
|
35
31
|
// Sometimes we need no English stop words,
|
|
36
32
|
// since they are almost all programming code.
|
|
37
|
-
this.pipeline.remove(
|
|
33
|
+
this.pipeline.remove(lunr.stopWordFilter);
|
|
38
34
|
}
|
|
39
35
|
if (removeDefaultStemmer) {
|
|
40
|
-
this.pipeline.remove(
|
|
36
|
+
this.pipeline.remove(lunr.stemmer);
|
|
41
37
|
}
|
|
42
38
|
// Override tokenizer when language `zh` is enabled.
|
|
43
39
|
if (language.includes("zh")) {
|
|
44
|
-
this.tokenizer =
|
|
40
|
+
this.tokenizer = lunr.zh.tokenizer;
|
|
45
41
|
}
|
|
46
42
|
this.ref("i");
|
|
47
43
|
this.field("t");
|
|
48
44
|
this.metadataWhitelist = ["position"];
|
|
49
45
|
documents.forEach((doc) => {
|
|
50
|
-
this.add(
|
|
46
|
+
this.add({
|
|
47
|
+
...doc,
|
|
51
48
|
// The ref must be a string.
|
|
52
|
-
i: doc.i.toString()
|
|
49
|
+
i: doc.i.toString(),
|
|
50
|
+
});
|
|
53
51
|
});
|
|
54
52
|
}),
|
|
55
53
|
}));
|
|
56
54
|
}
|
|
57
|
-
exports.buildIndex = buildIndex;
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.cutWordByUnderscore = void 0;
|
|
4
1
|
const splitRegExp = [/(_)([^_])/g, /([^_])(_)/g];
|
|
5
|
-
function cutWordByUnderscore(input) {
|
|
2
|
+
export function cutWordByUnderscore(input) {
|
|
6
3
|
return splitRegExp
|
|
7
4
|
.reduce((carry, re) => carry.replace(re, "$1\0$2"), input)
|
|
8
5
|
.split("\0");
|
|
9
6
|
}
|
|
10
|
-
exports.cutWordByUnderscore = cutWordByUnderscore;
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const debug = (0, debug_1.default)("search-local");
|
|
7
|
-
exports.debugVerbose = debug.extend("verbose");
|
|
8
|
-
exports.debugInfo = debug.extend("info");
|
|
9
|
-
exports.debugWarn = debug.extend("warn");
|
|
1
|
+
import createDebug from "debug";
|
|
2
|
+
const debug = createDebug("search-local");
|
|
3
|
+
export const debugVerbose = debug.extend("verbose");
|
|
4
|
+
export const debugInfo = debug.extend("info");
|
|
5
|
+
export const debugWarn = debug.extend("warn");
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const fs_1 = tslib_1.__importDefault(require("fs"));
|
|
6
|
-
const path_1 = tslib_1.__importDefault(require("path"));
|
|
7
|
-
const getIndexHash_1 = require("./getIndexHash");
|
|
8
|
-
function generate(config, dir) {
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { getIndexHash } from "./getIndexHash";
|
|
4
|
+
export function generate(config, dir) {
|
|
9
5
|
const { language, removeDefaultStopWordFilter, removeDefaultStemmer, highlightSearchTermsOnTargetPage, searchResultLimits, searchResultContextMaxLength, explicitSearchResultPath, searchBarShortcut, searchBarShortcutHint, searchBarPosition, docsPluginIdForPreferredVersion, indexDocs, searchContextByPaths, hideSearchBarWithNoSearchContext, useAllContextsWithNoSearchContext, } = config;
|
|
10
|
-
const indexHash =
|
|
6
|
+
const indexHash = getIndexHash(config);
|
|
11
7
|
const contents = [
|
|
12
8
|
`import lunr from ${JSON.stringify(require.resolve("lunr"))};`,
|
|
13
9
|
];
|
|
@@ -61,7 +57,6 @@ function generate(config, dir) {
|
|
|
61
57
|
: null)};`);
|
|
62
58
|
contents.push(`export const hideSearchBarWithNoSearchContext = ${JSON.stringify(!!hideSearchBarWithNoSearchContext)};`);
|
|
63
59
|
contents.push(`export const useAllContextsWithNoSearchContext = ${JSON.stringify(!!useAllContextsWithNoSearchContext)};`);
|
|
64
|
-
|
|
60
|
+
fs.writeFileSync(path.join(dir, "generated.js"), contents.join("\n"));
|
|
65
61
|
return searchIndexFilename;
|
|
66
62
|
}
|
|
67
|
-
exports.generate = generate;
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getCondensedText = void 0;
|
|
4
1
|
// We prepend and append whitespace for these tags.
|
|
5
2
|
// https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements
|
|
6
3
|
const BLOCK_TAGS = new Set([
|
|
@@ -41,7 +38,7 @@ const BLOCK_TAGS = new Set([
|
|
|
41
38
|
"td",
|
|
42
39
|
"th",
|
|
43
40
|
]);
|
|
44
|
-
function getCondensedText(element, $) {
|
|
41
|
+
export function getCondensedText(element, $) {
|
|
45
42
|
const getText = (element) => {
|
|
46
43
|
if (Array.isArray(element)) {
|
|
47
44
|
return element.map((item) => getText(item)).join("");
|
|
@@ -63,4 +60,3 @@ function getCondensedText(element, $) {
|
|
|
63
60
|
};
|
|
64
61
|
return getText(element).trim().replace(/\s+/g, " ");
|
|
65
62
|
}
|
|
66
|
-
exports.getCondensedText = getCondensedText;
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const crypto_1 = tslib_1.__importDefault(require("crypto"));
|
|
8
|
-
const klaw_sync_1 = tslib_1.__importDefault(require("klaw-sync"));
|
|
9
|
-
const debug_1 = require("./debug");
|
|
10
|
-
function getIndexHash(config) {
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import crypto from "crypto";
|
|
4
|
+
import klawSync from "klaw-sync";
|
|
5
|
+
import { debugInfo } from "./debug";
|
|
6
|
+
export function getIndexHash(config) {
|
|
11
7
|
if (!config.hashed) {
|
|
12
8
|
return null;
|
|
13
9
|
}
|
|
@@ -15,14 +11,14 @@ function getIndexHash(config) {
|
|
|
15
11
|
const scanFiles = (flagField, dirField) => {
|
|
16
12
|
if (config[flagField]) {
|
|
17
13
|
for (const dir of config[dirField]) {
|
|
18
|
-
if (!
|
|
14
|
+
if (!fs.existsSync(dir)) {
|
|
19
15
|
console.warn(`Warn: \`${dirField}\` doesn't exist: "${dir}".`);
|
|
20
16
|
}
|
|
21
|
-
else if (!
|
|
17
|
+
else if (!fs.lstatSync(dir).isDirectory()) {
|
|
22
18
|
console.warn(`Warn: \`${dirField}\` is not a directory: "${dir}".`);
|
|
23
19
|
}
|
|
24
20
|
else {
|
|
25
|
-
files.push(...(
|
|
21
|
+
files.push(...klawSync(dir, {
|
|
26
22
|
nodir: true,
|
|
27
23
|
filter: markdownFilter,
|
|
28
24
|
traverseAll: true,
|
|
@@ -34,23 +30,22 @@ function getIndexHash(config) {
|
|
|
34
30
|
scanFiles("indexDocs", "docsDir");
|
|
35
31
|
scanFiles("indexBlog", "blogDir");
|
|
36
32
|
if (files.length > 0) {
|
|
37
|
-
const md5sum =
|
|
33
|
+
const md5sum = crypto.createHash("md5");
|
|
38
34
|
// The version of this plugin should be counted in hash,
|
|
39
35
|
// since the index maybe changed between versions.
|
|
40
36
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
41
|
-
const pluginVersion = require(
|
|
42
|
-
|
|
37
|
+
const pluginVersion = require(path.resolve(__dirname, "../../../../package.json")).version;
|
|
38
|
+
debugInfo("using @easyops-cn/docusaurus-search-local v%s", pluginVersion);
|
|
43
39
|
md5sum.update(pluginVersion, "utf8");
|
|
44
40
|
for (const item of files) {
|
|
45
|
-
md5sum.update(
|
|
41
|
+
md5sum.update(fs.readFileSync(item.path));
|
|
46
42
|
}
|
|
47
43
|
const indexHash = md5sum.digest("hex").substring(0, 8);
|
|
48
|
-
|
|
44
|
+
debugInfo("the index hash is %j", indexHash);
|
|
49
45
|
return indexHash;
|
|
50
46
|
}
|
|
51
47
|
return null;
|
|
52
48
|
}
|
|
53
|
-
exports.getIndexHash = getIndexHash;
|
|
54
49
|
function markdownFilter(item) {
|
|
55
50
|
return item.path.endsWith(".md") || item.path.endsWith(".mdx");
|
|
56
51
|
}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const parseDocument_1 = require("./parseDocument");
|
|
7
|
-
const parsePage_1 = require("./parsePage");
|
|
8
|
-
function parse(html, type, url, { ignoreCssSelectors }) {
|
|
9
|
-
const $ = cheerio_1.default.load(html);
|
|
1
|
+
import cheerio from "cheerio";
|
|
2
|
+
import { parseDocument } from "./parseDocument";
|
|
3
|
+
import { parsePage } from "./parsePage";
|
|
4
|
+
export function parse(html, type, url, { ignoreCssSelectors }) {
|
|
5
|
+
const $ = cheerio.load(html);
|
|
10
6
|
// Remove copy buttons from code boxes
|
|
11
7
|
$('div[class^="mdxCodeBlock_"] button').remove();
|
|
12
8
|
if (ignoreCssSelectors) {
|
|
@@ -21,8 +17,7 @@ function parse(html, type, url, { ignoreCssSelectors }) {
|
|
|
21
17
|
.remove();
|
|
22
18
|
}
|
|
23
19
|
if (type === "page") {
|
|
24
|
-
return
|
|
20
|
+
return parsePage($, url);
|
|
25
21
|
}
|
|
26
|
-
return
|
|
22
|
+
return parseDocument($);
|
|
27
23
|
}
|
|
28
|
-
exports.parse = parse;
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.parseDocument = void 0;
|
|
4
|
-
const utils_common_1 = require("@docusaurus/utils-common");
|
|
5
|
-
const getCondensedText_1 = require("./getCondensedText");
|
|
1
|
+
import { blogPostContainerID } from "@docusaurus/utils-common";
|
|
2
|
+
import { getCondensedText } from "./getCondensedText";
|
|
6
3
|
const HEADINGS = "h1, h2, h3";
|
|
7
4
|
// const SUB_HEADINGS = "h2, h3";
|
|
8
|
-
function parseDocument($) {
|
|
5
|
+
export function parseDocument($) {
|
|
9
6
|
const $pageTitle = $("article h1").first();
|
|
10
7
|
const pageTitle = $pageTitle.text();
|
|
11
8
|
const sections = [];
|
|
@@ -46,7 +43,7 @@ function parseDocument($) {
|
|
|
46
43
|
else {
|
|
47
44
|
$firstElement = $h;
|
|
48
45
|
}
|
|
49
|
-
const blogPost = $(`#${
|
|
46
|
+
const blogPost = $(`#${blogPostContainerID}`);
|
|
50
47
|
if (blogPost.length) {
|
|
51
48
|
// Simplify blog post.
|
|
52
49
|
$firstElement = blogPost.children().first();
|
|
@@ -75,7 +72,7 @@ function parseDocument($) {
|
|
|
75
72
|
else {
|
|
76
73
|
$sectionElements = $h.nextUntil(HEADINGS);
|
|
77
74
|
}
|
|
78
|
-
const content =
|
|
75
|
+
const content = getCondensedText($sectionElements.get(), $);
|
|
79
76
|
sections.push({
|
|
80
77
|
title,
|
|
81
78
|
hash,
|
|
@@ -84,4 +81,3 @@ function parseDocument($) {
|
|
|
84
81
|
});
|
|
85
82
|
return { pageTitle, sections, breadcrumb };
|
|
86
83
|
}
|
|
87
|
-
exports.parseDocument = parseDocument;
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const debug_1 = require("./debug");
|
|
5
|
-
const getCondensedText_1 = require("./getCondensedText");
|
|
6
|
-
function parsePage($, url) {
|
|
1
|
+
import { debugWarn } from "./debug";
|
|
2
|
+
import { getCondensedText } from "./getCondensedText";
|
|
3
|
+
export function parsePage($, url) {
|
|
7
4
|
$("a[aria-hidden=true]").remove();
|
|
8
5
|
let $pageTitle = $("h1").first();
|
|
9
6
|
if ($pageTitle.length === 0) {
|
|
@@ -12,7 +9,7 @@ function parsePage($, url) {
|
|
|
12
9
|
const pageTitle = $pageTitle.text();
|
|
13
10
|
const $main = $("main");
|
|
14
11
|
if ($main.length === 0) {
|
|
15
|
-
|
|
12
|
+
debugWarn("page has no <main>, therefore no content was indexed for this page %o", url);
|
|
16
13
|
}
|
|
17
14
|
return {
|
|
18
15
|
pageTitle,
|
|
@@ -20,10 +17,9 @@ function parsePage($, url) {
|
|
|
20
17
|
{
|
|
21
18
|
title: pageTitle,
|
|
22
19
|
hash: "",
|
|
23
|
-
content: $main.length > 0 ?
|
|
20
|
+
content: $main.length > 0 ? getCondensedText($main.get(0), $).trim() : "",
|
|
24
21
|
},
|
|
25
22
|
],
|
|
26
23
|
breadcrumb: [],
|
|
27
24
|
};
|
|
28
25
|
}
|
|
29
|
-
exports.parsePage = parsePage;
|
|
@@ -1,78 +1,71 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
dirAllDocs[docIndex] = dirDocs = [];
|
|
47
|
-
}
|
|
48
|
-
dirDocs.push(doc);
|
|
49
|
-
if (!useAllContextsWithNoSearchContext) {
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import util from "util";
|
|
4
|
+
import { buildIndex } from "./buildIndex";
|
|
5
|
+
import { debugInfo } from "./debug";
|
|
6
|
+
import { processDocInfos } from "./processDocInfos";
|
|
7
|
+
import { scanDocuments } from "./scanDocuments";
|
|
8
|
+
const writeFileAsync = util.promisify(fs.writeFile);
|
|
9
|
+
export function postBuildFactory(config, searchIndexFilename) {
|
|
10
|
+
return async function postBuild(buildData) {
|
|
11
|
+
debugInfo("gathering documents");
|
|
12
|
+
const data = processDocInfos(buildData, config);
|
|
13
|
+
debugInfo("parsing documents");
|
|
14
|
+
for (const versionData of data) {
|
|
15
|
+
// Give every index entry a unique id so that the index does not need to store long URLs.
|
|
16
|
+
const allDocuments = await scanDocuments(versionData.paths, config);
|
|
17
|
+
debugInfo("building index");
|
|
18
|
+
const docsByDirMap = new Map();
|
|
19
|
+
const { searchContextByPaths, hideSearchBarWithNoSearchContext, useAllContextsWithNoSearchContext, } = config;
|
|
20
|
+
if (searchContextByPaths) {
|
|
21
|
+
const { baseUrl } = buildData;
|
|
22
|
+
const rootAllDocs = [];
|
|
23
|
+
if (!hideSearchBarWithNoSearchContext) {
|
|
24
|
+
docsByDirMap.set("", rootAllDocs);
|
|
25
|
+
}
|
|
26
|
+
let docIndex = 0;
|
|
27
|
+
for (const documents of allDocuments) {
|
|
28
|
+
rootAllDocs[docIndex] = [];
|
|
29
|
+
for (const doc of documents) {
|
|
30
|
+
if (doc.u.startsWith(baseUrl)) {
|
|
31
|
+
const uri = doc.u.substring(baseUrl.length);
|
|
32
|
+
const matchedPath = searchContextByPaths.find((path) => uri === path || uri.startsWith(`${path}/`));
|
|
33
|
+
if (matchedPath) {
|
|
34
|
+
let dirAllDocs = docsByDirMap.get(matchedPath);
|
|
35
|
+
if (!dirAllDocs) {
|
|
36
|
+
dirAllDocs = [];
|
|
37
|
+
docsByDirMap.set(matchedPath, dirAllDocs);
|
|
38
|
+
}
|
|
39
|
+
let dirDocs = dirAllDocs[docIndex];
|
|
40
|
+
if (!dirDocs) {
|
|
41
|
+
dirAllDocs[docIndex] = dirDocs = [];
|
|
42
|
+
}
|
|
43
|
+
dirDocs.push(doc);
|
|
44
|
+
if (!useAllContextsWithNoSearchContext) {
|
|
45
|
+
continue;
|
|
52
46
|
}
|
|
53
47
|
}
|
|
54
|
-
rootAllDocs[docIndex].push(doc);
|
|
55
|
-
}
|
|
56
|
-
docIndex++;
|
|
57
|
-
}
|
|
58
|
-
for (const [k, v] of docsByDirMap) {
|
|
59
|
-
const docsNotEmpty = v.filter((d) => !!d);
|
|
60
|
-
if (docsNotEmpty.length < v.length) {
|
|
61
|
-
docsByDirMap.set(k, docsNotEmpty);
|
|
62
48
|
}
|
|
49
|
+
rootAllDocs[docIndex].push(doc);
|
|
63
50
|
}
|
|
51
|
+
docIndex++;
|
|
64
52
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
(0, debug_1.debugInfo)(`writing index (/${k}) to disk`);
|
|
71
|
-
yield writeFileAsync(path_1.default.join(versionData.outDir, searchIndexFilename.replace("{dir}", k === "" ? "" : `-${k.replace(/\//g, "-")}`)), JSON.stringify(searchIndex), { encoding: "utf8" });
|
|
72
|
-
(0, debug_1.debugInfo)(`index (/${k}) written to disk successfully!`);
|
|
53
|
+
for (const [k, v] of docsByDirMap) {
|
|
54
|
+
const docsNotEmpty = v.filter((d) => !!d);
|
|
55
|
+
if (docsNotEmpty.length < v.length) {
|
|
56
|
+
docsByDirMap.set(k, docsNotEmpty);
|
|
57
|
+
}
|
|
73
58
|
}
|
|
74
59
|
}
|
|
75
|
-
|
|
60
|
+
else {
|
|
61
|
+
docsByDirMap.set("", allDocuments);
|
|
62
|
+
}
|
|
63
|
+
for (const [k, allDocs] of docsByDirMap) {
|
|
64
|
+
const searchIndex = buildIndex(allDocs, config);
|
|
65
|
+
debugInfo(`writing index (/${k}) to disk`);
|
|
66
|
+
await writeFileAsync(path.join(versionData.outDir, searchIndexFilename.replace("{dir}", k === "" ? "" : `-${k.replace(/\//g, "-")}`)), JSON.stringify(searchIndex), { encoding: "utf8" });
|
|
67
|
+
debugInfo(`index (/${k}) written to disk successfully!`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
76
70
|
};
|
|
77
71
|
}
|
|
78
|
-
exports.postBuildFactory = postBuildFactory;
|
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const path_1 = tslib_1.__importDefault(require("path"));
|
|
6
|
-
const debug_1 = require("./debug");
|
|
7
|
-
function processDocInfos({ routesPaths, outDir, baseUrl, siteConfig, plugins }, { indexDocs, indexBlog, indexPages, docsRouteBasePath, blogRouteBasePath, ignoreFiles, }) {
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { debugVerbose } from "./debug";
|
|
3
|
+
export function processDocInfos({ routesPaths, outDir, baseUrl, siteConfig, plugins }, { indexDocs, indexBlog, indexPages, docsRouteBasePath, blogRouteBasePath, ignoreFiles, }) {
|
|
8
4
|
const emptySet = new Set();
|
|
9
5
|
let versionData = new Map([[outDir, emptySet]]);
|
|
10
6
|
if (plugins) {
|
|
11
7
|
// Handle docs multi-instance.
|
|
12
8
|
const docsPlugins = plugins.filter((item) => item.name === "docusaurus-plugin-content-docs");
|
|
13
9
|
const loadedVersions = docsPlugins.flatMap((plugin) => plugin.content.loadedVersions);
|
|
14
|
-
|
|
10
|
+
debugVerbose("loadedVersions:", loadedVersions);
|
|
15
11
|
if (loadedVersions.length > 0) {
|
|
16
12
|
versionData = new Map();
|
|
17
13
|
for (const loadedVersion of loadedVersions) {
|
|
@@ -19,7 +15,7 @@ function processDocInfos({ routesPaths, outDir, baseUrl, siteConfig, plugins },
|
|
|
19
15
|
let versionOutDir = outDir;
|
|
20
16
|
// The last versions search-index should always be placed in the root since it is the one used from non-docs pages
|
|
21
17
|
if (!loadedVersion.isLast) {
|
|
22
|
-
versionOutDir =
|
|
18
|
+
versionOutDir = path.join(outDir, ...route.split("/").filter((i) => i));
|
|
23
19
|
}
|
|
24
20
|
// Merge docs which share the same `versionOutDir`.
|
|
25
21
|
let docs = versionData.get(versionOutDir);
|
|
@@ -31,7 +27,7 @@ function processDocInfos({ routesPaths, outDir, baseUrl, siteConfig, plugins },
|
|
|
31
27
|
docs.add(doc.permalink);
|
|
32
28
|
}
|
|
33
29
|
}
|
|
34
|
-
|
|
30
|
+
debugVerbose("versionData:", versionData);
|
|
35
31
|
}
|
|
36
32
|
}
|
|
37
33
|
// Create a list of files to index per document version. This will always include all pages and blogs.
|
|
@@ -52,7 +48,7 @@ function processDocInfos({ routesPaths, outDir, baseUrl, siteConfig, plugins },
|
|
|
52
48
|
return;
|
|
53
49
|
}
|
|
54
50
|
// ignore files
|
|
55
|
-
if (ignoreFiles
|
|
51
|
+
if (ignoreFiles?.some((reg) => {
|
|
56
52
|
if (typeof reg === "string") {
|
|
57
53
|
return route === reg;
|
|
58
54
|
}
|
|
@@ -63,7 +59,7 @@ function processDocInfos({ routesPaths, outDir, baseUrl, siteConfig, plugins },
|
|
|
63
59
|
if (indexBlog &&
|
|
64
60
|
blogRouteBasePath.some((basePath) => isSameOrSubRoute(route, basePath))) {
|
|
65
61
|
if (blogRouteBasePath.some((basePath) => isSameRoute(route, basePath) ||
|
|
66
|
-
isSameOrSubRoute(route,
|
|
62
|
+
isSameOrSubRoute(route, path.posix.join(basePath, "tags")))) {
|
|
67
63
|
// Do not index list of blog posts and tags filter pages
|
|
68
64
|
return;
|
|
69
65
|
}
|
|
@@ -100,7 +96,7 @@ function processDocInfos({ routesPaths, outDir, baseUrl, siteConfig, plugins },
|
|
|
100
96
|
})
|
|
101
97
|
.filter(Boolean)
|
|
102
98
|
.map(({ route, url, type }) => ({
|
|
103
|
-
filePath:
|
|
99
|
+
filePath: path.join(outDir, siteConfig.trailingSlash === false && route != ""
|
|
104
100
|
? `${route}.html`
|
|
105
101
|
: `${route}/index.html`),
|
|
106
102
|
url,
|
|
@@ -112,7 +108,6 @@ function processDocInfos({ routesPaths, outDir, baseUrl, siteConfig, plugins },
|
|
|
112
108
|
}
|
|
113
109
|
return result;
|
|
114
110
|
}
|
|
115
|
-
exports.processDocInfos = processDocInfos;
|
|
116
111
|
function isSameRoute(routeA, routeB) {
|
|
117
112
|
return addTrailingSlash(routeA) === addTrailingSlash(routeB);
|
|
118
113
|
}
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const path_1 = tslib_1.__importDefault(require("path"));
|
|
6
|
-
function processPluginOptions(options, { siteDir, siteConfig: { themeConfig }, }) {
|
|
7
|
-
var _a, _b;
|
|
8
|
-
const config = Object.assign({}, options);
|
|
1
|
+
import path from "path";
|
|
2
|
+
export function processPluginOptions(options, { siteDir, siteConfig: { themeConfig }, }) {
|
|
3
|
+
const config = { ...options };
|
|
9
4
|
ensureArray(config, "docsRouteBasePath");
|
|
10
5
|
ensureArray(config, "blogRouteBasePath");
|
|
11
6
|
ensureArray(config, "language");
|
|
@@ -15,16 +10,15 @@ function processPluginOptions(options, { siteDir, siteConfig: { themeConfig }, }
|
|
|
15
10
|
ensureArray(config, "ignoreCssSelectors");
|
|
16
11
|
config.docsRouteBasePath = config.docsRouteBasePath.map((basePath) => basePath.replace(/^\//, ""));
|
|
17
12
|
config.blogRouteBasePath = config.blogRouteBasePath.map((basePath) => basePath.replace(/^\//, ""));
|
|
18
|
-
config.docsDir = config.docsDir.map((dir) =>
|
|
19
|
-
config.blogDir = config.blogDir.map((dir) =>
|
|
13
|
+
config.docsDir = config.docsDir.map((dir) => path.resolve(siteDir, dir));
|
|
14
|
+
config.blogDir = config.blogDir.map((dir) => path.resolve(siteDir, dir));
|
|
20
15
|
if (config.searchBarPosition === "auto") {
|
|
21
|
-
const search =
|
|
16
|
+
const search = themeConfig.navbar?.items?.find((item) => item.type === "search");
|
|
22
17
|
config.searchBarPosition =
|
|
23
18
|
search && search.position === "left" ? "left" : "right";
|
|
24
19
|
}
|
|
25
20
|
return config;
|
|
26
21
|
}
|
|
27
|
-
exports.processPluginOptions = processPluginOptions;
|
|
28
22
|
function ensureArray(object, key) {
|
|
29
23
|
if (!Array.isArray(object[key])) {
|
|
30
24
|
object[key] = [object[key]];
|
|
@@ -1,57 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
const util_1 = tslib_1.__importDefault(require("util"));
|
|
8
|
-
const parse_1 = require("./parse");
|
|
9
|
-
const debug_1 = require("./debug");
|
|
10
|
-
const readFileAsync = util_1.default.promisify(fs_1.default.readFile);
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import util from "util";
|
|
4
|
+
import { parse } from "./parse";
|
|
5
|
+
import { debugVerbose } from "./debug";
|
|
6
|
+
const readFileAsync = util.promisify(fs.readFile);
|
|
11
7
|
let nextDocId = 0;
|
|
12
8
|
const getNextDocId = () => {
|
|
13
9
|
return (nextDocId += 1);
|
|
14
10
|
};
|
|
15
|
-
function scanDocuments(DocInfoWithFilePathList, config) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
if (section.content) {
|
|
43
|
-
contentDocuments.push({
|
|
44
|
-
i: getNextDocId(),
|
|
45
|
-
t: section.content,
|
|
46
|
-
s: section.title || pageTitle,
|
|
47
|
-
u: url,
|
|
48
|
-
h: section.hash,
|
|
49
|
-
p: titleId,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
11
|
+
export async function scanDocuments(DocInfoWithFilePathList, config) {
|
|
12
|
+
const titleDocuments = [];
|
|
13
|
+
const headingDocuments = [];
|
|
14
|
+
const contentDocuments = [];
|
|
15
|
+
const allDocuments = [titleDocuments, headingDocuments, contentDocuments];
|
|
16
|
+
await Promise.all(DocInfoWithFilePathList.map(async ({ filePath, url, type }) => {
|
|
17
|
+
debugVerbose(`parsing %s file %o of %o`, type, path.relative(process.cwd(), filePath), url);
|
|
18
|
+
const html = await readFileAsync(filePath, { encoding: "utf8" });
|
|
19
|
+
const { pageTitle, sections, breadcrumb } = parse(html, type, url, config);
|
|
20
|
+
const titleId = getNextDocId();
|
|
21
|
+
titleDocuments.push({
|
|
22
|
+
i: titleId,
|
|
23
|
+
t: pageTitle,
|
|
24
|
+
u: url,
|
|
25
|
+
b: breadcrumb,
|
|
26
|
+
});
|
|
27
|
+
for (const section of sections) {
|
|
28
|
+
if (section.title !== pageTitle) {
|
|
29
|
+
headingDocuments.push({
|
|
30
|
+
i: getNextDocId(),
|
|
31
|
+
t: section.title,
|
|
32
|
+
u: url,
|
|
33
|
+
h: section.hash,
|
|
34
|
+
p: titleId,
|
|
35
|
+
});
|
|
52
36
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
37
|
+
if (section.content) {
|
|
38
|
+
contentDocuments.push({
|
|
39
|
+
i: getNextDocId(),
|
|
40
|
+
t: section.content,
|
|
41
|
+
s: section.title || pageTitle,
|
|
42
|
+
u: url,
|
|
43
|
+
h: section.hash,
|
|
44
|
+
p: titleId,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}));
|
|
49
|
+
return allDocuments;
|
|
56
50
|
}
|
|
57
|
-
exports.scanDocuments = scanDocuments;
|
|
@@ -1,34 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const fs_1 = tslib_1.__importDefault(require("fs"));
|
|
6
|
-
const lunr_1 = tslib_1.__importDefault(require("lunr"));
|
|
7
|
-
const jieba_1 = tslib_1.__importDefault(require("@node-rs/jieba"));
|
|
8
|
-
const cutWordByUnderscore_1 = require("./cutWordByUnderscore");
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import lunr from "lunr";
|
|
3
|
+
import jieba from "@node-rs/jieba";
|
|
4
|
+
import { cutWordByUnderscore } from "./cutWordByUnderscore";
|
|
9
5
|
// https://zhuanlan.zhihu.com/p/33335629
|
|
10
6
|
const RegExpConsecutiveWord = /\w+|\p{Unified_Ideograph}+/u;
|
|
11
7
|
let userDictLoaded = false;
|
|
12
|
-
function loadUserDict(zhUserDict, zhUserDictPath) {
|
|
8
|
+
export function loadUserDict(zhUserDict, zhUserDictPath) {
|
|
13
9
|
if (userDictLoaded) {
|
|
14
10
|
return;
|
|
15
11
|
}
|
|
16
12
|
if (zhUserDict) {
|
|
17
|
-
|
|
13
|
+
jieba.loadDict(Buffer.from(zhUserDict));
|
|
18
14
|
}
|
|
19
15
|
else if (zhUserDictPath) {
|
|
20
|
-
|
|
16
|
+
jieba.loadDict(fs.readFileSync(zhUserDictPath));
|
|
21
17
|
}
|
|
22
18
|
userDictLoaded = true;
|
|
23
19
|
}
|
|
24
|
-
|
|
25
|
-
function tokenizer(input, metadata) {
|
|
20
|
+
export function tokenizer(input, metadata) {
|
|
26
21
|
if (input == null) {
|
|
27
22
|
return [];
|
|
28
23
|
}
|
|
29
24
|
if (Array.isArray(input)) {
|
|
30
25
|
return input.map(function (t) {
|
|
31
|
-
return new
|
|
26
|
+
return new lunr.Token(lunr.utils.asString(t).toLowerCase(), lunr.utils.clone(metadata));
|
|
32
27
|
});
|
|
33
28
|
}
|
|
34
29
|
const content = input.toString().toLowerCase();
|
|
@@ -43,14 +38,22 @@ function tokenizer(input, metadata) {
|
|
|
43
38
|
const word = match[0];
|
|
44
39
|
start += match.index;
|
|
45
40
|
if (/\w/.test(word[0])) {
|
|
46
|
-
tokens.push(new
|
|
41
|
+
tokens.push(new lunr.Token(word, {
|
|
42
|
+
...lunr.utils.clone(metadata),
|
|
43
|
+
position: [start, word.length],
|
|
44
|
+
index: tokens.length,
|
|
45
|
+
}));
|
|
47
46
|
// Try to cut `api_gateway` to `api` and `gateway`.
|
|
48
|
-
const subWords =
|
|
47
|
+
const subWords = cutWordByUnderscore(word);
|
|
49
48
|
if (subWords.length > 1) {
|
|
50
49
|
let i = 0;
|
|
51
50
|
for (const subWord of subWords) {
|
|
52
51
|
if (subWord[0] !== "_") {
|
|
53
|
-
tokens.push(new
|
|
52
|
+
tokens.push(new lunr.Token(subWord, {
|
|
53
|
+
...lunr.utils.clone(metadata),
|
|
54
|
+
position: [start + i, subWord.length],
|
|
55
|
+
index: tokens.length,
|
|
56
|
+
}));
|
|
54
57
|
}
|
|
55
58
|
i += subWord.length;
|
|
56
59
|
}
|
|
@@ -58,8 +61,12 @@ function tokenizer(input, metadata) {
|
|
|
58
61
|
start += word.length;
|
|
59
62
|
}
|
|
60
63
|
else {
|
|
61
|
-
for (const zhWord of
|
|
62
|
-
tokens.push(new
|
|
64
|
+
for (const zhWord of jieba.cut(word)) {
|
|
65
|
+
tokens.push(new lunr.Token(zhWord, {
|
|
66
|
+
...lunr.utils.clone(metadata),
|
|
67
|
+
position: [start, zhWord.length],
|
|
68
|
+
index: tokens.length,
|
|
69
|
+
}));
|
|
63
70
|
start += zhWord.length;
|
|
64
71
|
}
|
|
65
72
|
}
|
|
@@ -67,4 +74,3 @@ function tokenizer(input, metadata) {
|
|
|
67
74
|
}
|
|
68
75
|
return tokens;
|
|
69
76
|
}
|
|
70
|
-
exports.tokenizer = tokenizer;
|
|
@@ -1,39 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
indexDocs: utils_validation_1.Joi.boolean().default(true),
|
|
10
|
-
indexBlog: utils_validation_1.Joi.boolean().default(true),
|
|
11
|
-
indexPages: utils_validation_1.Joi.boolean().default(false),
|
|
1
|
+
import { Joi } from "@docusaurus/utils-validation";
|
|
2
|
+
const isStringOrArrayOfStrings = Joi.alternatives().try(Joi.string(), Joi.array().items(Joi.string()));
|
|
3
|
+
const isBooleanOrString = Joi.alternatives().try(Joi.boolean(), Joi.string());
|
|
4
|
+
const isArrayOfStringsOrRegExpsOrStringOrRegExp = Joi.alternatives().try(Joi.array().items(Joi.alternatives().try(Joi.string(), Joi.object().regex())), Joi.string(), Joi.object().regex());
|
|
5
|
+
const schema = Joi.object({
|
|
6
|
+
indexDocs: Joi.boolean().default(true),
|
|
7
|
+
indexBlog: Joi.boolean().default(true),
|
|
8
|
+
indexPages: Joi.boolean().default(false),
|
|
12
9
|
docsRouteBasePath: isStringOrArrayOfStrings.default(["docs"]),
|
|
13
10
|
blogRouteBasePath: isStringOrArrayOfStrings.default(["blog"]),
|
|
14
11
|
language: isStringOrArrayOfStrings.default(["en"]),
|
|
15
12
|
hashed: isBooleanOrString.default(false),
|
|
16
13
|
docsDir: isStringOrArrayOfStrings.default(["docs"]),
|
|
17
14
|
blogDir: isStringOrArrayOfStrings.default(["blog"]),
|
|
18
|
-
removeDefaultStopWordFilter:
|
|
19
|
-
removeDefaultStemmer:
|
|
20
|
-
highlightSearchTermsOnTargetPage:
|
|
21
|
-
searchResultLimits:
|
|
22
|
-
searchResultContextMaxLength:
|
|
23
|
-
explicitSearchResultPath:
|
|
15
|
+
removeDefaultStopWordFilter: Joi.boolean().default(false),
|
|
16
|
+
removeDefaultStemmer: Joi.boolean().default(false),
|
|
17
|
+
highlightSearchTermsOnTargetPage: Joi.boolean().default(false),
|
|
18
|
+
searchResultLimits: Joi.number().default(8),
|
|
19
|
+
searchResultContextMaxLength: Joi.number().default(50),
|
|
20
|
+
explicitSearchResultPath: Joi.boolean().default(false),
|
|
24
21
|
ignoreFiles: isArrayOfStringsOrRegExpsOrStringOrRegExp.default([]),
|
|
25
22
|
ignoreCssSelectors: isStringOrArrayOfStrings.default([]),
|
|
26
|
-
searchBarShortcut:
|
|
27
|
-
searchBarShortcutHint:
|
|
28
|
-
searchBarPosition:
|
|
29
|
-
docsPluginIdForPreferredVersion:
|
|
30
|
-
zhUserDict:
|
|
31
|
-
zhUserDictPath:
|
|
32
|
-
searchContextByPaths:
|
|
33
|
-
hideSearchBarWithNoSearchContext:
|
|
34
|
-
useAllContextsWithNoSearchContext:
|
|
23
|
+
searchBarShortcut: Joi.boolean().default(true),
|
|
24
|
+
searchBarShortcutHint: Joi.boolean().default(true),
|
|
25
|
+
searchBarPosition: Joi.string().default("auto"),
|
|
26
|
+
docsPluginIdForPreferredVersion: Joi.string(),
|
|
27
|
+
zhUserDict: Joi.string(),
|
|
28
|
+
zhUserDictPath: Joi.string(),
|
|
29
|
+
searchContextByPaths: Joi.array().items(Joi.string()),
|
|
30
|
+
hideSearchBarWithNoSearchContext: Joi.boolean().default(false),
|
|
31
|
+
useAllContextsWithNoSearchContext: Joi.boolean().default(false),
|
|
35
32
|
});
|
|
36
|
-
function validateOptions({ options, validate, }) {
|
|
33
|
+
export function validateOptions({ options, validate, }) {
|
|
37
34
|
return validate(schema, options || {});
|
|
38
35
|
}
|
|
39
|
-
exports.validateOptions = validateOptions;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateTrimmer = void 0;
|
|
4
|
-
function generateTrimmer(wordCharacters) {
|
|
1
|
+
export function generateTrimmer(wordCharacters) {
|
|
5
2
|
const startRegex = new RegExp("^[^" + wordCharacters + "]+", "u");
|
|
6
3
|
const endRegex = new RegExp("[^" + wordCharacters + "]+$", "u");
|
|
7
4
|
return function (token) {
|
|
@@ -10,4 +7,3 @@ function generateTrimmer(wordCharacters) {
|
|
|
10
7
|
});
|
|
11
8
|
};
|
|
12
9
|
}
|
|
13
|
-
exports.generateTrimmer = generateTrimmer;
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.lunrLanguageZh = void 0;
|
|
4
|
-
const generateTrimmer_1 = require("./generateTrimmer");
|
|
1
|
+
import { generateTrimmer } from "./generateTrimmer";
|
|
5
2
|
// `lunr-languages/lunr.stemmer.support` is required.
|
|
6
|
-
function lunrLanguageZh(lunr, tokenizer) {
|
|
7
|
-
lunr.trimmerSupport.generateTrimmer =
|
|
3
|
+
export function lunrLanguageZh(lunr, tokenizer) {
|
|
4
|
+
lunr.trimmerSupport.generateTrimmer = generateTrimmer;
|
|
8
5
|
lunr.zh = function () {
|
|
9
6
|
this.pipeline.reset();
|
|
10
7
|
this.pipeline.add(lunr.zh.trimmer, lunr.zh.stopWordFilter);
|
|
@@ -25,4 +22,3 @@ function lunrLanguageZh(lunr, tokenizer) {
|
|
|
25
22
|
lunr.zh.stopWordFilter = lunr.generateStopWordFilter("的 一 不 在 人 有 是 为 以 于 上 他 而 后 之 来 及 了 因 下 可 到 由 这 与 也 此 但 并 个 其 已 无 小 我 们 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 从 到 得 打 凡 儿 尔 该 各 给 跟 和 何 还 即 几 既 看 据 距 靠 啦 了 另 么 每 们 嘛 拿 哪 那 您 凭 且 却 让 仍 啥 如 若 使 谁 虽 随 同 所 她 哇 嗡 往 哪 些 向 沿 哟 用 于 咱 则 怎 曾 至 致 着 诸 自".split(" "));
|
|
26
23
|
lunr.Pipeline.registerFunction(lunr.zh.stopWordFilter, "stopWordFilter-zh");
|
|
27
24
|
}
|
|
28
|
-
exports.lunrLanguageZh = lunrLanguageZh;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@easyops-cn/docusaurus-search-local",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "An offline/local search plugin for Docusaurus
|
|
3
|
+
"version": "0.37.2",
|
|
4
|
+
"description": "An offline/local search plugin for Docusaurus v3",
|
|
5
5
|
"repository": "https://github.com/easyops-cn/docusaurus-search-local",
|
|
6
6
|
"homepage": "https://github.com/easyops-cn/docusaurus-search-local",
|
|
7
7
|
"scripts": {
|
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
},
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@docusaurus/plugin-content-docs": "^2
|
|
30
|
-
"@docusaurus/theme-translations": "^2
|
|
31
|
-
"@docusaurus/utils": "^2
|
|
32
|
-
"@docusaurus/utils-common": "^2
|
|
33
|
-
"@docusaurus/utils-validation": "^2
|
|
29
|
+
"@docusaurus/plugin-content-docs": "^2 || ^3",
|
|
30
|
+
"@docusaurus/theme-translations": "^2 || ^3",
|
|
31
|
+
"@docusaurus/utils": "^2 || ^3",
|
|
32
|
+
"@docusaurus/utils-common": "^2 || ^3",
|
|
33
|
+
"@docusaurus/utils-validation": "^2 || ^3",
|
|
34
34
|
"@easyops-cn/autocomplete.js": "^0.38.1",
|
|
35
35
|
"@node-rs/jieba": "^1.6.0",
|
|
36
36
|
"cheerio": "^1.0.0-rc.3",
|
|
@@ -44,10 +44,10 @@
|
|
|
44
44
|
"tslib": "^2.4.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@docusaurus/module-type-aliases": "^
|
|
48
|
-
"@docusaurus/theme-common": "^
|
|
49
|
-
"@docusaurus/
|
|
50
|
-
"@
|
|
47
|
+
"@docusaurus/module-type-aliases": "^3.0.0",
|
|
48
|
+
"@docusaurus/theme-common": "^3.0.0",
|
|
49
|
+
"@docusaurus/tsconfig": "3.0.0",
|
|
50
|
+
"@docusaurus/types": "^3.0.0",
|
|
51
51
|
"@types/cheerio": "^0.22.31",
|
|
52
52
|
"@types/debug": "^4.1.5",
|
|
53
53
|
"@types/fs-extra": "^9.0.2",
|
|
@@ -55,17 +55,17 @@
|
|
|
55
55
|
"@types/klaw-sync": "^6.0.0",
|
|
56
56
|
"@types/lunr": "^2.3.3",
|
|
57
57
|
"@types/node": "^18.0.0",
|
|
58
|
-
"@types/react": "^18.
|
|
58
|
+
"@types/react": "^18.2.37",
|
|
59
59
|
"@types/react-helmet": "^6.1.0",
|
|
60
60
|
"@types/react-router-dom": "^5.1.6",
|
|
61
61
|
"concurrently": "^7.0.0",
|
|
62
62
|
"copyfiles": "^2.4.0",
|
|
63
63
|
"rimraf": "^3.0.2",
|
|
64
|
-
"typescript": "
|
|
64
|
+
"typescript": "~5.2.2"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
|
-
"@docusaurus/theme-common": "^2
|
|
68
|
-
"react": "^
|
|
69
|
-
"react-dom": "^
|
|
67
|
+
"@docusaurus/theme-common": "^2 || ^3",
|
|
68
|
+
"react": "^18.2.0",
|
|
69
|
+
"react-dom": "^18.2.0"
|
|
70
70
|
}
|
|
71
71
|
}
|