docusaurus-plugin-mcp-server 0.6.0 → 0.7.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/dist/adapters-entry.d.mts +1 -1
- package/dist/adapters-entry.d.ts +1 -1
- package/dist/adapters-entry.js +253 -121
- package/dist/adapters-entry.js.map +1 -1
- package/dist/adapters-entry.mjs +252 -120
- package/dist/adapters-entry.mjs.map +1 -1
- package/dist/cli/verify.js +250 -119
- package/dist/cli/verify.js.map +1 -1
- package/dist/cli/verify.mjs +250 -119
- package/dist/cli/verify.mjs.map +1 -1
- package/dist/{index-CzA4FjeE.d.mts → index-4g0ZZK3z.d.mts} +33 -0
- package/dist/{index-CzA4FjeE.d.ts → index-4g0ZZK3z.d.ts} +33 -0
- package/dist/index.d.mts +287 -7
- package/dist/index.d.ts +287 -7
- package/dist/index.js +382 -143
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +378 -143
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/adapters-entry.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import fs from 'fs-extra';
|
|
2
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
2
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
4
3
|
import { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js';
|
|
5
4
|
import { z } from 'zod';
|
|
6
5
|
import FlexSearch from 'flexsearch';
|
|
6
|
+
import fs from 'fs-extra';
|
|
7
|
+
import 'http';
|
|
7
8
|
|
|
8
9
|
// src/mcp/server.ts
|
|
9
10
|
var FIELD_WEIGHTS = {
|
|
@@ -136,19 +137,126 @@ async function importSearchIndex(data) {
|
|
|
136
137
|
}
|
|
137
138
|
return index;
|
|
138
139
|
}
|
|
140
|
+
var FlexSearchProvider = class {
|
|
141
|
+
name = "flexsearch";
|
|
142
|
+
docs = null;
|
|
143
|
+
searchIndex = null;
|
|
144
|
+
ready = false;
|
|
145
|
+
async initialize(_context, initData) {
|
|
146
|
+
if (!initData) {
|
|
147
|
+
throw new Error("[FlexSearch] SearchProviderInitData required for FlexSearch provider");
|
|
148
|
+
}
|
|
149
|
+
if (initData.docs && initData.indexData) {
|
|
150
|
+
this.docs = initData.docs;
|
|
151
|
+
this.searchIndex = await importSearchIndex(initData.indexData);
|
|
152
|
+
this.ready = true;
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (initData.docsPath && initData.indexPath) {
|
|
156
|
+
if (await fs.pathExists(initData.docsPath)) {
|
|
157
|
+
this.docs = await fs.readJson(initData.docsPath);
|
|
158
|
+
} else {
|
|
159
|
+
throw new Error(`[FlexSearch] Docs file not found: ${initData.docsPath}`);
|
|
160
|
+
}
|
|
161
|
+
if (await fs.pathExists(initData.indexPath)) {
|
|
162
|
+
const indexData = await fs.readJson(initData.indexPath);
|
|
163
|
+
this.searchIndex = await importSearchIndex(indexData);
|
|
164
|
+
} else {
|
|
165
|
+
throw new Error(`[FlexSearch] Search index not found: ${initData.indexPath}`);
|
|
166
|
+
}
|
|
167
|
+
this.ready = true;
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
throw new Error(
|
|
171
|
+
"[FlexSearch] Invalid init data: must provide either file paths (docsPath, indexPath) or pre-loaded data (docs, indexData)"
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
isReady() {
|
|
175
|
+
return this.ready && this.docs !== null && this.searchIndex !== null;
|
|
176
|
+
}
|
|
177
|
+
async search(query, options) {
|
|
178
|
+
if (!this.isReady() || !this.docs || !this.searchIndex) {
|
|
179
|
+
throw new Error("[FlexSearch] Provider not initialized");
|
|
180
|
+
}
|
|
181
|
+
const limit = options?.limit ?? 5;
|
|
182
|
+
return searchIndex(this.searchIndex, this.docs, query, { limit });
|
|
183
|
+
}
|
|
184
|
+
async getDocument(route) {
|
|
185
|
+
if (!this.docs) {
|
|
186
|
+
throw new Error("[FlexSearch] Provider not initialized");
|
|
187
|
+
}
|
|
188
|
+
if (this.docs[route]) {
|
|
189
|
+
return this.docs[route];
|
|
190
|
+
}
|
|
191
|
+
const normalizedRoute = route.startsWith("/") ? route : `/${route}`;
|
|
192
|
+
const withoutSlash = route.startsWith("/") ? route.slice(1) : route;
|
|
193
|
+
return this.docs[normalizedRoute] ?? this.docs[withoutSlash] ?? null;
|
|
194
|
+
}
|
|
195
|
+
async healthCheck() {
|
|
196
|
+
if (!this.isReady()) {
|
|
197
|
+
return { healthy: false, message: "FlexSearch provider not initialized" };
|
|
198
|
+
}
|
|
199
|
+
const docCount = this.docs ? Object.keys(this.docs).length : 0;
|
|
200
|
+
return {
|
|
201
|
+
healthy: true,
|
|
202
|
+
message: `FlexSearch provider ready with ${docCount} documents`
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Get all loaded documents (for compatibility with existing server code)
|
|
207
|
+
*/
|
|
208
|
+
getDocs() {
|
|
209
|
+
return this.docs;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Get the FlexSearch index (for compatibility with existing server code)
|
|
213
|
+
*/
|
|
214
|
+
getSearchIndex() {
|
|
215
|
+
return this.searchIndex;
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
// src/providers/loader.ts
|
|
220
|
+
async function loadSearchProvider(specifier) {
|
|
221
|
+
if (specifier === "flexsearch") {
|
|
222
|
+
return new FlexSearchProvider();
|
|
223
|
+
}
|
|
224
|
+
try {
|
|
225
|
+
const module = await import(specifier);
|
|
226
|
+
const ProviderClass = module.default;
|
|
227
|
+
if (typeof ProviderClass === "function") {
|
|
228
|
+
const instance = new ProviderClass();
|
|
229
|
+
if (!isSearchProvider(instance)) {
|
|
230
|
+
throw new Error(
|
|
231
|
+
`Invalid search provider module "${specifier}": does not implement SearchProvider interface`
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
return instance;
|
|
235
|
+
}
|
|
236
|
+
if (isSearchProvider(ProviderClass)) {
|
|
237
|
+
return ProviderClass;
|
|
238
|
+
}
|
|
239
|
+
throw new Error(
|
|
240
|
+
`Invalid search provider module "${specifier}": must export a default class or SearchProvider instance`
|
|
241
|
+
);
|
|
242
|
+
} catch (error) {
|
|
243
|
+
if (error instanceof Error && error.message.includes("Cannot find module")) {
|
|
244
|
+
throw new Error(
|
|
245
|
+
`Search provider module not found: "${specifier}". Check the path or package name.`
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
throw error;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
function isSearchProvider(obj) {
|
|
252
|
+
if (!obj || typeof obj !== "object") {
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
const provider = obj;
|
|
256
|
+
return typeof provider.name === "string" && typeof provider.initialize === "function" && typeof provider.isReady === "function" && typeof provider.search === "function";
|
|
257
|
+
}
|
|
139
258
|
|
|
140
259
|
// src/mcp/tools/docs-search.ts
|
|
141
|
-
function executeDocsSearch(params, index, docs) {
|
|
142
|
-
const { query, limit = 5 } = params;
|
|
143
|
-
if (!query || typeof query !== "string" || query.trim().length === 0) {
|
|
144
|
-
throw new Error("Query parameter is required and must be a non-empty string");
|
|
145
|
-
}
|
|
146
|
-
const effectiveLimit = Math.min(Math.max(1, limit), 20);
|
|
147
|
-
const results = searchIndex(index, docs, query.trim(), {
|
|
148
|
-
limit: effectiveLimit
|
|
149
|
-
});
|
|
150
|
-
return results;
|
|
151
|
-
}
|
|
152
260
|
function formatSearchResults(results, baseUrl) {
|
|
153
261
|
if (results.length === 0) {
|
|
154
262
|
return "No matching documents found.";
|
|
@@ -174,28 +282,6 @@ function formatSearchResults(results, baseUrl) {
|
|
|
174
282
|
}
|
|
175
283
|
|
|
176
284
|
// src/mcp/tools/docs-get-page.ts
|
|
177
|
-
function executeDocsGetPage(params, docs) {
|
|
178
|
-
const { route } = params;
|
|
179
|
-
if (!route || typeof route !== "string") {
|
|
180
|
-
throw new Error("Route parameter is required and must be a string");
|
|
181
|
-
}
|
|
182
|
-
let normalizedRoute = route.trim();
|
|
183
|
-
if (!normalizedRoute.startsWith("/")) {
|
|
184
|
-
normalizedRoute = "/" + normalizedRoute;
|
|
185
|
-
}
|
|
186
|
-
if (normalizedRoute.length > 1 && normalizedRoute.endsWith("/")) {
|
|
187
|
-
normalizedRoute = normalizedRoute.slice(0, -1);
|
|
188
|
-
}
|
|
189
|
-
const doc = docs[normalizedRoute];
|
|
190
|
-
if (!doc) {
|
|
191
|
-
const altRoute = normalizedRoute.slice(1);
|
|
192
|
-
if (docs[altRoute]) {
|
|
193
|
-
return docs[altRoute] ?? null;
|
|
194
|
-
}
|
|
195
|
-
return null;
|
|
196
|
-
}
|
|
197
|
-
return doc;
|
|
198
|
-
}
|
|
199
285
|
function formatPageContent(doc, baseUrl) {
|
|
200
286
|
if (!doc) {
|
|
201
287
|
return "Page not found. Please check the route path and try again.";
|
|
@@ -240,52 +326,6 @@ function extractSection(markdown, headingId, headings) {
|
|
|
240
326
|
}
|
|
241
327
|
|
|
242
328
|
// src/mcp/tools/docs-get-section.ts
|
|
243
|
-
function executeDocsGetSection(params, docs) {
|
|
244
|
-
const { route, headingId } = params;
|
|
245
|
-
if (!route || typeof route !== "string") {
|
|
246
|
-
throw new Error("Route parameter is required and must be a string");
|
|
247
|
-
}
|
|
248
|
-
if (!headingId || typeof headingId !== "string") {
|
|
249
|
-
throw new Error("HeadingId parameter is required and must be a string");
|
|
250
|
-
}
|
|
251
|
-
let normalizedRoute = route.trim();
|
|
252
|
-
if (!normalizedRoute.startsWith("/")) {
|
|
253
|
-
normalizedRoute = "/" + normalizedRoute;
|
|
254
|
-
}
|
|
255
|
-
if (normalizedRoute.length > 1 && normalizedRoute.endsWith("/")) {
|
|
256
|
-
normalizedRoute = normalizedRoute.slice(0, -1);
|
|
257
|
-
}
|
|
258
|
-
const doc = docs[normalizedRoute];
|
|
259
|
-
if (!doc) {
|
|
260
|
-
return {
|
|
261
|
-
content: null,
|
|
262
|
-
doc: null,
|
|
263
|
-
headingText: null,
|
|
264
|
-
availableHeadings: []
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
const availableHeadings = doc.headings.map((h) => ({
|
|
268
|
-
id: h.id,
|
|
269
|
-
text: h.text,
|
|
270
|
-
level: h.level
|
|
271
|
-
}));
|
|
272
|
-
const heading = doc.headings.find((h) => h.id === headingId.trim());
|
|
273
|
-
if (!heading) {
|
|
274
|
-
return {
|
|
275
|
-
content: null,
|
|
276
|
-
doc,
|
|
277
|
-
headingText: null,
|
|
278
|
-
availableHeadings
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
const content = extractSection(doc.markdown, headingId.trim(), doc.headings);
|
|
282
|
-
return {
|
|
283
|
-
content,
|
|
284
|
-
doc,
|
|
285
|
-
headingText: heading.text,
|
|
286
|
-
availableHeadings
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
329
|
function formatSectionContent(result, headingId, baseUrl) {
|
|
290
330
|
if (!result.doc) {
|
|
291
331
|
return "Page not found. Please check the route path and try again.";
|
|
@@ -322,8 +362,7 @@ function isDataConfig(config) {
|
|
|
322
362
|
}
|
|
323
363
|
var McpDocsServer = class {
|
|
324
364
|
config;
|
|
325
|
-
|
|
326
|
-
searchIndex = null;
|
|
365
|
+
searchProvider = null;
|
|
327
366
|
mcpServer;
|
|
328
367
|
initialized = false;
|
|
329
368
|
constructor(config) {
|
|
@@ -356,18 +395,26 @@ var McpDocsServer = class {
|
|
|
356
395
|
},
|
|
357
396
|
async ({ query, limit }) => {
|
|
358
397
|
await this.initialize();
|
|
359
|
-
if (!this.
|
|
398
|
+
if (!this.searchProvider || !this.searchProvider.isReady()) {
|
|
360
399
|
return {
|
|
361
400
|
content: [{ type: "text", text: "Server not initialized. Please try again." }],
|
|
362
401
|
isError: true
|
|
363
402
|
};
|
|
364
403
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
404
|
+
try {
|
|
405
|
+
const results = await this.searchProvider.search(query, { limit });
|
|
406
|
+
return {
|
|
407
|
+
content: [
|
|
408
|
+
{ type: "text", text: formatSearchResults(results, this.config.baseUrl) }
|
|
409
|
+
]
|
|
410
|
+
};
|
|
411
|
+
} catch (error) {
|
|
412
|
+
console.error("[MCP] Search error:", error);
|
|
413
|
+
return {
|
|
414
|
+
content: [{ type: "text", text: `Search error: ${String(error)}` }],
|
|
415
|
+
isError: true
|
|
416
|
+
};
|
|
417
|
+
}
|
|
371
418
|
}
|
|
372
419
|
);
|
|
373
420
|
this.mcpServer.registerTool(
|
|
@@ -380,16 +427,24 @@ var McpDocsServer = class {
|
|
|
380
427
|
},
|
|
381
428
|
async ({ route }) => {
|
|
382
429
|
await this.initialize();
|
|
383
|
-
if (!this.
|
|
430
|
+
if (!this.searchProvider || !this.searchProvider.isReady()) {
|
|
384
431
|
return {
|
|
385
432
|
content: [{ type: "text", text: "Server not initialized. Please try again." }],
|
|
386
433
|
isError: true
|
|
387
434
|
};
|
|
388
435
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
436
|
+
try {
|
|
437
|
+
const doc = await this.getDocument(route);
|
|
438
|
+
return {
|
|
439
|
+
content: [{ type: "text", text: formatPageContent(doc, this.config.baseUrl) }]
|
|
440
|
+
};
|
|
441
|
+
} catch (error) {
|
|
442
|
+
console.error("[MCP] Get page error:", error);
|
|
443
|
+
return {
|
|
444
|
+
content: [{ type: "text", text: `Error getting page: ${String(error)}` }],
|
|
445
|
+
isError: true
|
|
446
|
+
};
|
|
447
|
+
}
|
|
393
448
|
}
|
|
394
449
|
);
|
|
395
450
|
this.mcpServer.registerTool(
|
|
@@ -405,26 +460,95 @@ var McpDocsServer = class {
|
|
|
405
460
|
},
|
|
406
461
|
async ({ route, headingId }) => {
|
|
407
462
|
await this.initialize();
|
|
408
|
-
if (!this.
|
|
463
|
+
if (!this.searchProvider || !this.searchProvider.isReady()) {
|
|
409
464
|
return {
|
|
410
465
|
content: [{ type: "text", text: "Server not initialized. Please try again." }],
|
|
411
466
|
isError: true
|
|
412
467
|
};
|
|
413
468
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
{
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
469
|
+
try {
|
|
470
|
+
const doc = await this.getDocument(route);
|
|
471
|
+
if (!doc) {
|
|
472
|
+
return {
|
|
473
|
+
content: [
|
|
474
|
+
{
|
|
475
|
+
type: "text",
|
|
476
|
+
text: formatSectionContent(
|
|
477
|
+
{ content: null, doc: null, headingText: null, availableHeadings: [] },
|
|
478
|
+
headingId,
|
|
479
|
+
this.config.baseUrl
|
|
480
|
+
)
|
|
481
|
+
}
|
|
482
|
+
]
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
const availableHeadings = doc.headings.map((h) => ({
|
|
486
|
+
id: h.id,
|
|
487
|
+
text: h.text,
|
|
488
|
+
level: h.level
|
|
489
|
+
}));
|
|
490
|
+
const heading = doc.headings.find((h) => h.id === headingId.trim());
|
|
491
|
+
if (!heading) {
|
|
492
|
+
return {
|
|
493
|
+
content: [
|
|
494
|
+
{
|
|
495
|
+
type: "text",
|
|
496
|
+
text: formatSectionContent(
|
|
497
|
+
{ content: null, doc, headingText: null, availableHeadings },
|
|
498
|
+
headingId,
|
|
499
|
+
this.config.baseUrl
|
|
500
|
+
)
|
|
501
|
+
}
|
|
502
|
+
]
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
const sectionContent = extractSection(doc.markdown, headingId.trim(), doc.headings);
|
|
506
|
+
return {
|
|
507
|
+
content: [
|
|
508
|
+
{
|
|
509
|
+
type: "text",
|
|
510
|
+
text: formatSectionContent(
|
|
511
|
+
{ content: sectionContent, doc, headingText: heading.text, availableHeadings },
|
|
512
|
+
headingId,
|
|
513
|
+
this.config.baseUrl
|
|
514
|
+
)
|
|
515
|
+
}
|
|
516
|
+
]
|
|
517
|
+
};
|
|
518
|
+
} catch (error) {
|
|
519
|
+
console.error("[MCP] Get section error:", error);
|
|
520
|
+
return {
|
|
521
|
+
content: [{ type: "text", text: `Error getting section: ${String(error)}` }],
|
|
522
|
+
isError: true
|
|
523
|
+
};
|
|
524
|
+
}
|
|
423
525
|
}
|
|
424
526
|
);
|
|
425
527
|
}
|
|
426
528
|
/**
|
|
427
|
-
*
|
|
529
|
+
* Get a document by route using the search provider
|
|
530
|
+
*/
|
|
531
|
+
async getDocument(route) {
|
|
532
|
+
if (!this.searchProvider) {
|
|
533
|
+
return null;
|
|
534
|
+
}
|
|
535
|
+
if (this.searchProvider.getDocument) {
|
|
536
|
+
return this.searchProvider.getDocument(route);
|
|
537
|
+
}
|
|
538
|
+
if (this.searchProvider instanceof FlexSearchProvider) {
|
|
539
|
+
const docs = this.searchProvider.getDocs();
|
|
540
|
+
if (!docs) return null;
|
|
541
|
+
if (docs[route]) {
|
|
542
|
+
return docs[route];
|
|
543
|
+
}
|
|
544
|
+
const normalizedRoute = route.startsWith("/") ? route : `/${route}`;
|
|
545
|
+
const withoutSlash = route.startsWith("/") ? route.slice(1) : route;
|
|
546
|
+
return docs[normalizedRoute] ?? docs[withoutSlash] ?? null;
|
|
547
|
+
}
|
|
548
|
+
return null;
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Load docs and search index using the configured search provider
|
|
428
552
|
*
|
|
429
553
|
* For file-based config: reads from disk
|
|
430
554
|
* For data config: uses pre-loaded data directly
|
|
@@ -434,24 +558,26 @@ var McpDocsServer = class {
|
|
|
434
558
|
return;
|
|
435
559
|
}
|
|
436
560
|
try {
|
|
561
|
+
const searchSpecifier = this.config.search ?? "flexsearch";
|
|
562
|
+
this.searchProvider = await loadSearchProvider(searchSpecifier);
|
|
563
|
+
const providerContext = {
|
|
564
|
+
baseUrl: this.config.baseUrl ?? "",
|
|
565
|
+
serverName: this.config.name,
|
|
566
|
+
serverVersion: this.config.version ?? "1.0.0",
|
|
567
|
+
outputDir: ""
|
|
568
|
+
// Not relevant for runtime
|
|
569
|
+
};
|
|
570
|
+
const initData = {};
|
|
437
571
|
if (isDataConfig(this.config)) {
|
|
438
|
-
|
|
439
|
-
|
|
572
|
+
initData.docs = this.config.docs;
|
|
573
|
+
initData.indexData = this.config.searchIndexData;
|
|
440
574
|
} else if (isFileConfig(this.config)) {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
} else {
|
|
444
|
-
throw new Error(`Docs file not found: ${this.config.docsPath}`);
|
|
445
|
-
}
|
|
446
|
-
if (await fs.pathExists(this.config.indexPath)) {
|
|
447
|
-
const indexData = await fs.readJson(this.config.indexPath);
|
|
448
|
-
this.searchIndex = await importSearchIndex(indexData);
|
|
449
|
-
} else {
|
|
450
|
-
throw new Error(`Search index not found: ${this.config.indexPath}`);
|
|
451
|
-
}
|
|
575
|
+
initData.docsPath = this.config.docsPath;
|
|
576
|
+
initData.indexPath = this.config.indexPath;
|
|
452
577
|
} else {
|
|
453
578
|
throw new Error("Invalid server config: must provide either file paths or pre-loaded data");
|
|
454
579
|
}
|
|
580
|
+
await this.searchProvider.initialize(providerContext, initData);
|
|
455
581
|
this.initialized = true;
|
|
456
582
|
} catch (error) {
|
|
457
583
|
console.error("[MCP] Failed to initialize:", error);
|
|
@@ -512,12 +638,18 @@ var McpDocsServer = class {
|
|
|
512
638
|
* Useful for health checks and debugging
|
|
513
639
|
*/
|
|
514
640
|
async getStatus() {
|
|
641
|
+
let docCount = 0;
|
|
642
|
+
if (this.searchProvider instanceof FlexSearchProvider) {
|
|
643
|
+
const docs = this.searchProvider.getDocs();
|
|
644
|
+
docCount = docs ? Object.keys(docs).length : 0;
|
|
645
|
+
}
|
|
515
646
|
return {
|
|
516
647
|
name: this.config.name,
|
|
517
648
|
version: this.config.version ?? "1.0.0",
|
|
518
649
|
initialized: this.initialized,
|
|
519
|
-
docCount
|
|
520
|
-
baseUrl: this.config.baseUrl
|
|
650
|
+
docCount,
|
|
651
|
+
baseUrl: this.config.baseUrl,
|
|
652
|
+
searchProvider: this.searchProvider?.name
|
|
521
653
|
};
|
|
522
654
|
}
|
|
523
655
|
/**
|