@farming-labs/theme 0.2.75 → 0.2.78
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/docs-api.mjs +98 -30
- package/package.json +2 -2
package/dist/docs-api.mjs
CHANGED
|
@@ -4,8 +4,8 @@ import { BoundedRouteCache } from "./bounded-route-cache.mjs";
|
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import matter from "gray-matter";
|
|
7
|
-
import { DEFAULT_A2A_AGENT_CARD_ROUTE, DEFAULT_AGENT_SKILLS_ARCHIVE_ROUTE_PATTERN, DEFAULT_AGENT_SKILLS_INDEX_ROUTE, DEFAULT_AGENT_SKILLS_ROUTE_PREFIX, DEFAULT_API_CATALOG_ROUTE, DEFAULT_LEGACY_SKILLS_INDEX_ROUTE, DEFAULT_SITEMAP_MD_DOCS_ROUTE, DOCS_AGENT_MANIFEST_FORMAT, DOCS_AGENT_MANIFEST_SCHEMA_URI, DOCS_AGENT_MANIFEST_VERSION, DOCS_MARKDOWN_SECTION_INDEX_FORMAT, acceptsDocsMarkdown, buildDocsAskAIContext, buildDocsConfigMap, buildDocsDiagnostics, createDocsAgentTraceContext, createDocsAgentTraceId, createDocsMarkdownResponse, createDocsRobotsResponse, createDocsSitemapResponse, createDocsStandardsDiscoveryResponse, detectDocsMarkdownAgentRequest, emitDocsAgentTraceEvent, emitDocsAnalyticsEvent, emitDocsTelemetryAgentSurfaceEvent, emitDocsTelemetryProjectEvent, formatDocsAskAIPackageHints, getDocsAgentManifestLinkHeader, getDocsDiscoveryLinkHeader, getDocsLlmsTxtMaxCharsIssue, getDocsMcpProtectedResourceMetadataRoutes, hasDocsMarkdownSignatureAgent, inferDocsTelemetryAgentSurface, isDocsConfigRequest, isDocsDiagnosticsRequest, normalizeDocsRelated, normalizePageAgentFrontmatter, performDocsSearch, performDocsSearchWithMetadata, renderDocsLlmsTxt, renderDocsMarkdownDocument, resolveAskAISearchRequestConfig, resolveChangelogConfig, resolveDocsAgentContractMcpTools, resolveDocsAudienceMdxContent, resolveDocsI18n, resolveDocsLlmsTxtRequest, resolveDocsLlmsTxtSections, resolveDocsLocale, resolveDocsMetadataBaseUrl, resolveDocsPublishedAgentSkill, resolveDocsRequestApiRoute, resolveDocsRetrievalLastModified, resolveDocsSearchAudience,
|
|
8
|
-
import { buildApiReferenceOpenApiDocumentAsync, createDocsMcpHttpHandler, createFilesystemDocsMcpSource, readDocsSitemapManifest,
|
|
7
|
+
import { DEFAULT_A2A_AGENT_CARD_ROUTE, DEFAULT_AGENT_SKILLS_ARCHIVE_ROUTE_PATTERN, DEFAULT_AGENT_SKILLS_INDEX_ROUTE, DEFAULT_AGENT_SKILLS_ROUTE_PREFIX, DEFAULT_API_CATALOG_ROUTE, DEFAULT_LEGACY_SKILLS_INDEX_ROUTE, DEFAULT_SITEMAP_MD_DOCS_ROUTE, DOCS_AGENT_MANIFEST_FORMAT, DOCS_AGENT_MANIFEST_SCHEMA_URI, DOCS_AGENT_MANIFEST_VERSION, DOCS_CONTENT_CHANGES_FORMAT, DOCS_CONTENT_CHANGES_RESPONSE_VALUE, DOCS_MARKDOWN_SECTION_INDEX_FORMAT, acceptsDocsMarkdown, buildDocsAskAIContext, buildDocsConfigMap, buildDocsDiagnostics, buildDocsSearchFacets, createDocsAgentTraceContext, createDocsAgentTraceId, createDocsContentChangeFeed, createDocsContentChangesHttpResponse, createDocsMarkdownResponse, createDocsRobotsResponse, createDocsSitemapResponse, createDocsStandardsDiscoveryResponse, detectDocsMarkdownAgentRequest, emitDocsAgentTraceEvent, emitDocsAnalyticsEvent, emitDocsTelemetryAgentSurfaceEvent, emitDocsTelemetryProjectEvent, formatDocsAskAIPackageHints, getDocsAgentManifestLinkHeader, getDocsDiscoveryLinkHeader, getDocsLlmsTxtMaxCharsIssue, getDocsMcpProtectedResourceMetadataRoutes, hasDocsMarkdownSignatureAgent, inferDocsTelemetryAgentSurface, isDocsConfigRequest, isDocsContentChangesRequest, isDocsDiagnosticsRequest, normalizeDocsRelated, normalizePageAgentFrontmatter, performDocsSearch, performDocsSearchWithMetadata, renderDocsLlmsTxt, renderDocsMarkdownDocument, resolveAskAISearchRequestConfig, resolveChangelogConfig, resolveDocsAgentContractMcpTools, resolveDocsAudienceMdxContent, resolveDocsContentChangesConfig, resolveDocsI18n, resolveDocsLlmsTxtRequest, resolveDocsLlmsTxtSections, resolveDocsLocale, resolveDocsMetadataBaseUrl, resolveDocsPublishedAgentSkill, resolveDocsRequestApiRoute, resolveDocsRetrievalLastModified, resolveDocsSearchAudience, resolveDocsSearchError, resolveDocsSearchRequest, resolveDocsSitemapConfig, resolveDocsStandardsDiscoveryRequest, resolvePageSidebarFolderIndexBehavior, resolveSearchRequestConfig, selectDocsLlmsTxtContent, stripGeneratedAgentProvenance } from "@farming-labs/docs";
|
|
8
|
+
import { buildApiReferenceOpenApiDocumentAsync, createDocsMcpHttpHandler, createFilesystemDocsMcpSource, readDocsSitemapManifest, resolveApiReferenceOpenApiDiscovery, resolveConfiguredAgentSkills, resolveDocsMcpConfig } from "@farming-labs/docs/server";
|
|
9
9
|
|
|
10
10
|
//#region src/docs-api.ts
|
|
11
11
|
/**
|
|
@@ -197,22 +197,11 @@ function isRobotsDiscoveryEnabled(robots) {
|
|
|
197
197
|
function isApiReferenceOpenApiRequest(url) {
|
|
198
198
|
return url.searchParams.get("format")?.trim() === "openapi";
|
|
199
199
|
}
|
|
200
|
-
function
|
|
201
|
-
const apiReference = resolveApiReferenceConfig(value);
|
|
202
|
-
if (!apiReference.enabled) return { enabled: false };
|
|
203
|
-
return {
|
|
204
|
-
enabled: true,
|
|
205
|
-
url: `${DEFAULT_DOCS_API_ROUTE}?format=openapi`,
|
|
206
|
-
urlSource: "default",
|
|
207
|
-
source: apiReference.specUrl ? "configured" : "generated",
|
|
208
|
-
specUrl: apiReference.specUrl,
|
|
209
|
-
apiReferencePath: `/${apiReference.path}`
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
function buildAgentSpec({ origin, entry, apiRoute, apiCatalog, i18n, search, mcp, feedback, llms, sitemap, robots, openapi, publishedSkills = [], agentCard }) {
|
|
200
|
+
function buildAgentSpec({ origin, entry, apiRoute, apiCatalog, i18n, search, contentChanges, mcp, feedback, llms, sitemap, robots, openapi, publishedSkills = [], agentCard }) {
|
|
213
201
|
const normalizedEntry = normalizePathSegment(entry) || "docs";
|
|
214
202
|
const localesEnabled = i18n !== null;
|
|
215
203
|
const searchEnabled = isSearchEnabled(search);
|
|
204
|
+
const contentChangesEnabled = resolveDocsContentChangesConfig(contentChanges).enabled;
|
|
216
205
|
const sitemapConfig = resolveDocsSitemapConfig(sitemap, { baseUrl: llms.baseUrl });
|
|
217
206
|
const robotsEnabled = isRobotsDiscoveryEnabled(robots);
|
|
218
207
|
const llmsSections = resolveDocsLlmsTxtSections(llms);
|
|
@@ -250,6 +239,7 @@ function buildAgentSpec({ origin, entry, apiRoute, apiCatalog, i18n, search, mcp
|
|
|
250
239
|
skills: true,
|
|
251
240
|
mcp: mcp.enabled,
|
|
252
241
|
search: searchEnabled,
|
|
242
|
+
contentChanges: contentChangesEnabled,
|
|
253
243
|
sitemap: sitemapConfig.enabled,
|
|
254
244
|
robots: robotsEnabled,
|
|
255
245
|
structuredData: true,
|
|
@@ -272,6 +262,7 @@ function buildAgentSpec({ origin, entry, apiRoute, apiCatalog, i18n, search, mcp
|
|
|
272
262
|
agentSpecQuery: `${apiRoute}?agent=spec`,
|
|
273
263
|
agents: `${apiRoute}?format=agents`,
|
|
274
264
|
openapi: `${apiRoute}?format=openapi`,
|
|
265
|
+
...contentChangesEnabled ? { contentChanges: `${apiRoute}?audience=agent&response=${DOCS_CONTENT_CHANGES_RESPONSE_VALUE}` } : {},
|
|
275
266
|
...apiCatalog ? {
|
|
276
267
|
apiCatalog: DEFAULT_API_CATALOG_ROUTE,
|
|
277
268
|
apiCatalogQuery: `${apiRoute}?format=api-catalog`
|
|
@@ -406,13 +397,16 @@ function buildAgentSpec({ origin, entry, apiRoute, apiCatalog, i18n, search, mcp
|
|
|
406
397
|
endpoint: `${apiRoute}?query={query}`,
|
|
407
398
|
agentEndpoint: `${apiRoute}?query={query}&audience=agent`,
|
|
408
399
|
structuredAgentEndpoint: `${apiRoute}?query={query}&audience=agent&response=structured`,
|
|
400
|
+
facetsEndpoint: `${apiRoute}?audience=agent&response=facets`,
|
|
409
401
|
method: "GET",
|
|
410
402
|
queryParam: "query",
|
|
411
403
|
localeParam: "lang",
|
|
412
404
|
audienceParam: "audience",
|
|
413
405
|
responseParam: "response",
|
|
414
406
|
structuredResponseValue: "structured",
|
|
407
|
+
facetsResponseValue: "facets",
|
|
415
408
|
responseFormat: "docs-search.v1",
|
|
409
|
+
facetsResponseFormat: "docs-search-facets.v1",
|
|
416
410
|
filterParams: {
|
|
417
411
|
framework: "framework",
|
|
418
412
|
version: "version",
|
|
@@ -426,9 +420,36 @@ function buildAgentSpec({ origin, entry, apiRoute, apiCatalog, i18n, search, mcp
|
|
|
426
420
|
"tags"
|
|
427
421
|
],
|
|
428
422
|
warningsField: "warnings",
|
|
423
|
+
facetParam: "facet",
|
|
424
|
+
limitParam: "limit",
|
|
425
|
+
cursorParam: "cursor",
|
|
426
|
+
nextCursorField: "nextCursor",
|
|
427
|
+
hasMoreField: "hasMore",
|
|
428
|
+
totalField: "total",
|
|
429
429
|
defaultAudience: "human",
|
|
430
430
|
supportedAudiences: ["human", "agent"]
|
|
431
431
|
},
|
|
432
|
+
contentChanges: {
|
|
433
|
+
enabled: contentChangesEnabled,
|
|
434
|
+
endpoint: contentChangesEnabled ? `${apiRoute}?audience=agent&response=${DOCS_CONTENT_CHANGES_RESPONSE_VALUE}` : null,
|
|
435
|
+
method: "GET",
|
|
436
|
+
audienceParam: "audience",
|
|
437
|
+
defaultAudience: "agent",
|
|
438
|
+
supportedAudiences: ["human", "agent"],
|
|
439
|
+
responseParam: "response",
|
|
440
|
+
responseValue: DOCS_CONTENT_CHANGES_RESPONSE_VALUE,
|
|
441
|
+
sinceParam: "since",
|
|
442
|
+
format: DOCS_CONTENT_CHANGES_FORMAT,
|
|
443
|
+
generationField: "indexGeneration",
|
|
444
|
+
resetRequiredField: "resetRequired",
|
|
445
|
+
modes: [
|
|
446
|
+
"snapshot",
|
|
447
|
+
"delta",
|
|
448
|
+
"reset"
|
|
449
|
+
],
|
|
450
|
+
bodyFree: true,
|
|
451
|
+
etag: true
|
|
452
|
+
},
|
|
432
453
|
agents: {
|
|
433
454
|
enabled: true,
|
|
434
455
|
file: "AGENTS.md",
|
|
@@ -1302,7 +1323,7 @@ function renderMarkdownDocument(page, options = {}) {
|
|
|
1302
1323
|
sitemap: options.sitemap
|
|
1303
1324
|
});
|
|
1304
1325
|
}
|
|
1305
|
-
function renderSkillDocument({ origin, entry, apiRoute, apiCatalog, search, mcp, feedback, llms, sitemap, robots, openapi }) {
|
|
1326
|
+
function renderSkillDocument({ origin, entry, apiRoute, apiCatalog, search, contentChanges, mcp, feedback, llms, sitemap, robots, openapi }) {
|
|
1306
1327
|
const normalizedEntry = normalizePathSegment(entry) || "docs";
|
|
1307
1328
|
const siteTitle = compactSkillText(llms.siteTitle ?? "Documentation");
|
|
1308
1329
|
const siteDescription = llms.siteDescription ? compactSkillText(llms.siteDescription) : void 0;
|
|
@@ -1326,7 +1347,8 @@ function renderSkillDocument({ origin, entry, apiRoute, apiCatalog, search, mcp,
|
|
|
1326
1347
|
lines.push("", "## When To Use", "Use this skill when you need to read or implement against this documentation site.", "", "## Start Here", `- Fetch ${DEFAULT_AGENT_SPEC_WELL_KNOWN_JSON_ROUTE}; fall back to ${DEFAULT_AGENT_SPEC_WELL_KNOWN_ROUTE} or ${agentSpecRoute}.`);
|
|
1327
1348
|
if (apiCatalog) lines.push(`- Fetch ${DEFAULT_API_CATALOG_ROUTE} for the standards-based API catalog.`);
|
|
1328
1349
|
lines.push(`- Fetch ${DEFAULT_AGENT_SKILLS_INDEX_ROUTE} to discover the published site skill and verify its SHA-256 digest.`, `- Fetch /${normalizedEntry}.md for the root docs page.`, `- Fetch /${normalizedEntry}/{slug}.md for page-specific context.`, `- Fetch /${normalizedEntry}/{slug}.md?sections to list section IDs and size estimates before requesting ?section={id}.`, "- You can also request text/markdown from normal page URLs.");
|
|
1329
|
-
if (searchEnabled) lines.push(`- Search with ${apiRoute}?query={query}&audience=agent&response=structured when you do not know the page; add framework, version, package, or repeated tags filters when scope matters.`);
|
|
1350
|
+
if (searchEnabled) lines.push(`- Discover valid search filters with ${apiRoute}?audience=agent&response=facets before choosing framework, version, package, or tag values; continue a large field with facet={field}, limit={limit}, and its nextCursor.`, `- Search with ${apiRoute}?query={query}&audience=agent&response=structured when you do not know the page; add framework, version, package, or repeated tags filters when scope matters.`);
|
|
1351
|
+
if (resolveDocsContentChangesConfig(contentChanges).enabled) lines.push(`- Synchronize changed documents with ${apiRoute}?audience=agent&response=${DOCS_CONTENT_CHANGES_RESPONSE_VALUE}; pass indexGeneration as since on the next request and clear stale state when resetRequired is true.`);
|
|
1330
1352
|
if (openapi.enabled && openapiUrl) lines.push(`- Fetch ${openapiUrl} for the machine-readable OpenAPI schema before scraping API reference pages.`);
|
|
1331
1353
|
if (llms.enabled) {
|
|
1332
1354
|
lines.push(`- Use ${DEFAULT_LLMS_TXT_ROUTE} for a compact docs index.`, `- Use ${DEFAULT_LLMS_FULL_TXT_ROUTE} for full markdown context.`);
|
|
@@ -1362,7 +1384,7 @@ function renderSkillDocument({ origin, entry, apiRoute, apiCatalog, search, mcp,
|
|
|
1362
1384
|
lines.push("", "## Reusable Framework Skills", "For framework setup, CLI, page actions, Ask AI, or configuration work, install the reusable Farming Labs skills:", "", "```sh", "npx skills add farming-labs/docs", "```");
|
|
1363
1385
|
return lines.join("\n");
|
|
1364
1386
|
}
|
|
1365
|
-
function renderAgentsDocument({ origin, entry, apiRoute, apiCatalog, search, mcp, feedback, llms, sitemap, robots, openapi }) {
|
|
1387
|
+
function renderAgentsDocument({ origin, entry, apiRoute, apiCatalog, search, contentChanges, mcp, feedback, llms, sitemap, robots, openapi }) {
|
|
1366
1388
|
const normalizedEntry = normalizePathSegment(entry) || "docs";
|
|
1367
1389
|
const siteTitle = compactSkillText(llms.siteTitle ?? "Documentation");
|
|
1368
1390
|
const siteDescription = llms.siteDescription ? compactSkillText(llms.siteDescription) : void 0;
|
|
@@ -1391,7 +1413,8 @@ function renderAgentsDocument({ origin, entry, apiRoute, apiCatalog, search, mcp
|
|
|
1391
1413
|
if (sitemapConfig.xml.enabled) lines.push(`- Use ${sitemapConfig.xml.route} for canonical URLs and freshness metadata.`);
|
|
1392
1414
|
}
|
|
1393
1415
|
if (robotsEnabled) lines.push(`- Check ${DEFAULT_ROBOTS_TXT_ROUTE} before crawling broadly.`);
|
|
1394
|
-
if (searchEnabled) lines.push(`- Search with ${apiRoute}?query={query}&audience=agent&response=structured when the route is unknown; add framework, version, package, or repeated tags filters when scope matters.`);
|
|
1416
|
+
if (searchEnabled) lines.push(`- Discover valid search filters with ${apiRoute}?audience=agent&response=facets before choosing framework, version, package, or tag values; continue a large field with facet={field}, limit={limit}, and its nextCursor.`, `- Search with ${apiRoute}?query={query}&audience=agent&response=structured when the route is unknown; add framework, version, package, or repeated tags filters when scope matters.`);
|
|
1417
|
+
if (resolveDocsContentChangesConfig(contentChanges).enabled) lines.push(`- Synchronize changed documents with ${apiRoute}?audience=agent&response=${DOCS_CONTENT_CHANGES_RESPONSE_VALUE}; pass indexGeneration as since on the next request and clear stale state when resetRequired is true.`);
|
|
1395
1418
|
if (openapi.enabled && openapiUrl) lines.push(`- Fetch ${openapiUrl} before scraping API reference pages; prefer schemas over prose.`);
|
|
1396
1419
|
if (mcp.enabled) lines.push(`- Use MCP at ${DEFAULT_MCP_PUBLIC_ROUTE} or ${DEFAULT_MCP_WELL_KNOWN_ROUTE} when your environment supports MCP tools.`);
|
|
1397
1420
|
if (feedback.enabled) lines.push(`- Read ${feedback.schemaRoute} before posting feedback to ${feedback.route}.`);
|
|
@@ -2462,8 +2485,10 @@ function readApiReferenceConfig(root) {
|
|
|
2462
2485
|
const pathMatch = block.match(/path\s*:\s*["']([^"']+)["']/);
|
|
2463
2486
|
const routeRootMatch = block.match(/routeRoot\s*:\s*["']([^"']+)["']/);
|
|
2464
2487
|
const specUrlMatch = block.match(/specUrl\s*:\s*["']([^"']+)["']/);
|
|
2488
|
+
const catalogTargetsMatch = block.match(/catalogTargets\s*:\s*\[([\s\S]*?)\]/);
|
|
2465
2489
|
const rendererMatch = block.match(/renderer\s*:\s*["'](fumadocs|scalar)["']/);
|
|
2466
2490
|
const excludeMatch = block.match(/exclude\s*:\s*\[([\s\S]*?)\]/);
|
|
2491
|
+
const catalogTargets = catalogTargetsMatch?.[1] === void 0 ? void 0 : Array.from(catalogTargetsMatch[1].matchAll(/["']([^"']+)["']/g)).map((match) => match[1]).filter(Boolean);
|
|
2467
2492
|
const exclude = excludeMatch?.[1] === void 0 ? void 0 : Array.from(excludeMatch[1].matchAll(/["']([^"']+)["']/g)).map((match) => match[1]).filter(Boolean);
|
|
2468
2493
|
const renderer = rendererMatch?.[1] === "fumadocs" || rendererMatch?.[1] === "scalar" ? rendererMatch[1] : void 0;
|
|
2469
2494
|
return {
|
|
@@ -2471,6 +2496,7 @@ function readApiReferenceConfig(root) {
|
|
|
2471
2496
|
path: pathMatch?.[1],
|
|
2472
2497
|
routeRoot: routeRootMatch?.[1],
|
|
2473
2498
|
specUrl: specUrlMatch?.[1],
|
|
2499
|
+
catalogTargets,
|
|
2474
2500
|
renderer,
|
|
2475
2501
|
exclude
|
|
2476
2502
|
};
|
|
@@ -2532,6 +2558,8 @@ function createDocsAPI(options) {
|
|
|
2532
2558
|
apiRoute: configuredApiRoute
|
|
2533
2559
|
} : cloudConfig;
|
|
2534
2560
|
const searchConfig = options?.search;
|
|
2561
|
+
const contentChangesConfig = resolveDocsContentChangesConfig(options?.agent?.contentChanges, { staticExport: options?.staticExport === true });
|
|
2562
|
+
const contentChangeFeed = createDocsContentChangeFeed(options?.agent?.contentChanges);
|
|
2535
2563
|
const llmsConfig = resolveLlmsTxtConfig(options?.llmsTxt, readLlmsTxtConfig(root));
|
|
2536
2564
|
const apiCatalogEnabled = options?.apiCatalog ?? llmsConfig.apiCatalog ?? true;
|
|
2537
2565
|
const sitemapConfig = options?.sitemap ?? readSitemapConfig(root);
|
|
@@ -2564,6 +2592,7 @@ function createDocsAPI(options) {
|
|
|
2564
2592
|
contentDir,
|
|
2565
2593
|
telemetry: options?.telemetry,
|
|
2566
2594
|
search: searchConfig,
|
|
2595
|
+
agent: options?.agent,
|
|
2567
2596
|
ai: aiConfig,
|
|
2568
2597
|
cloud: effectiveCloudConfig,
|
|
2569
2598
|
i18n: i18nConfig ?? void 0,
|
|
@@ -2585,6 +2614,7 @@ function createDocsAPI(options) {
|
|
|
2585
2614
|
setConfigMapFallback("entry", entry);
|
|
2586
2615
|
setConfigMapFallback("ai", Object.keys(aiConfig).length > 0 ? aiConfig : void 0);
|
|
2587
2616
|
setConfigMapFallback("search", searchConfig);
|
|
2617
|
+
setConfigMapFallback("agent", options?.agent);
|
|
2588
2618
|
setConfigMapFallback("i18n", i18nConfig ?? void 0);
|
|
2589
2619
|
setConfigMapFallback("mcp", rawMcpConfig);
|
|
2590
2620
|
setConfigMapFallback("apiReference", apiReferenceConfig);
|
|
@@ -2782,6 +2812,7 @@ function createDocsAPI(options) {
|
|
|
2782
2812
|
apiCatalog: apiCatalogEnabled,
|
|
2783
2813
|
i18n,
|
|
2784
2814
|
search: searchConfig,
|
|
2815
|
+
contentChanges: contentChangesConfig.enabled,
|
|
2785
2816
|
mcp: mcpConfig,
|
|
2786
2817
|
feedback: agentFeedbackConfig,
|
|
2787
2818
|
llms: llmsConfig,
|
|
@@ -2802,6 +2833,7 @@ function createDocsAPI(options) {
|
|
|
2802
2833
|
apiRoute,
|
|
2803
2834
|
i18n,
|
|
2804
2835
|
search: searchConfig,
|
|
2836
|
+
contentChanges: contentChangesConfig.enabled,
|
|
2805
2837
|
mcp: mcpConfig,
|
|
2806
2838
|
feedback: agentFeedbackConfig,
|
|
2807
2839
|
llms: llmsConfig,
|
|
@@ -2867,6 +2899,7 @@ function createDocsAPI(options) {
|
|
|
2867
2899
|
apiCatalog: apiCatalogEnabled,
|
|
2868
2900
|
i18n,
|
|
2869
2901
|
search: searchConfig,
|
|
2902
|
+
contentChanges: contentChangesConfig.enabled,
|
|
2870
2903
|
mcp: mcpConfig,
|
|
2871
2904
|
feedback: agentFeedbackConfig,
|
|
2872
2905
|
llms: llmsConfig,
|
|
@@ -2882,6 +2915,7 @@ function createDocsAPI(options) {
|
|
|
2882
2915
|
apiCatalog: apiCatalogEnabled,
|
|
2883
2916
|
i18n,
|
|
2884
2917
|
search: searchConfig,
|
|
2918
|
+
contentChanges: contentChangesConfig.enabled,
|
|
2885
2919
|
mcp: mcpConfig,
|
|
2886
2920
|
feedback: agentFeedbackConfig,
|
|
2887
2921
|
llms: llmsConfig,
|
|
@@ -2897,6 +2931,23 @@ function createDocsAPI(options) {
|
|
|
2897
2931
|
"X-Robots-Tag": "noindex"
|
|
2898
2932
|
} });
|
|
2899
2933
|
}
|
|
2934
|
+
if (isDocsContentChangesRequest(url)) {
|
|
2935
|
+
if (!contentChangesConfig.enabled) return new Response("Not Found", {
|
|
2936
|
+
status: 404,
|
|
2937
|
+
headers: {
|
|
2938
|
+
"Content-Type": "text/plain; charset=utf-8",
|
|
2939
|
+
"X-Robots-Tag": "noindex"
|
|
2940
|
+
}
|
|
2941
|
+
});
|
|
2942
|
+
return createDocsContentChangesHttpResponse({
|
|
2943
|
+
request,
|
|
2944
|
+
feed: contentChangeFeed,
|
|
2945
|
+
pages: getIndexes(ctx),
|
|
2946
|
+
search: searchConfig,
|
|
2947
|
+
locale: ctx.locale,
|
|
2948
|
+
baseUrl: markdownMetadataBaseUrl || url.origin
|
|
2949
|
+
});
|
|
2950
|
+
}
|
|
2900
2951
|
if (isApiReferenceOpenApiRequest(url)) {
|
|
2901
2952
|
if (!openapiDiscovery.enabled) return new Response("Not Found", {
|
|
2902
2953
|
status: 404,
|
|
@@ -2962,6 +3013,7 @@ function createDocsAPI(options) {
|
|
|
2962
3013
|
apiRoute: requestApiRoute,
|
|
2963
3014
|
apiCatalog: apiCatalogEnabled,
|
|
2964
3015
|
search: searchConfig,
|
|
3016
|
+
contentChanges: contentChangesConfig.enabled,
|
|
2965
3017
|
mcp: mcpConfig,
|
|
2966
3018
|
feedback: agentFeedbackConfig,
|
|
2967
3019
|
llms: llmsConfig,
|
|
@@ -2994,6 +3046,7 @@ function createDocsAPI(options) {
|
|
|
2994
3046
|
apiCatalog: apiCatalogEnabled,
|
|
2995
3047
|
i18n,
|
|
2996
3048
|
search: searchConfig,
|
|
3049
|
+
contentChanges: contentChangesConfig.enabled,
|
|
2997
3050
|
mcp: mcpConfig,
|
|
2998
3051
|
feedback: agentFeedbackConfig,
|
|
2999
3052
|
llms: llmsConfig,
|
|
@@ -3166,9 +3219,16 @@ function createDocsAPI(options) {
|
|
|
3166
3219
|
}
|
|
3167
3220
|
const query = url.searchParams.get("query")?.trim();
|
|
3168
3221
|
const audience = resolveDocsSearchAudience(url.searchParams.get("audience"));
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3222
|
+
let searchRequest;
|
|
3223
|
+
try {
|
|
3224
|
+
searchRequest = resolveDocsSearchRequest(url.searchParams);
|
|
3225
|
+
} catch (error) {
|
|
3226
|
+
const searchError = resolveDocsSearchError(error);
|
|
3227
|
+
if (!searchError) throw error;
|
|
3228
|
+
return Response.json({ error: searchError }, { status: 400 });
|
|
3229
|
+
}
|
|
3230
|
+
const { filters, structured, facets, facet, cursor, limit } = searchRequest;
|
|
3231
|
+
if (!query && !structured && !facets) return new Response("[]", { headers: { "Content-Type": "application/json" } });
|
|
3172
3232
|
const searchOptions = {
|
|
3173
3233
|
pages: getIndexes(ctx),
|
|
3174
3234
|
query: query ?? "",
|
|
@@ -3179,19 +3239,27 @@ function createDocsAPI(options) {
|
|
|
3179
3239
|
pathname: url.searchParams.get("pathname") ?? void 0,
|
|
3180
3240
|
siteTitle: llmsConfig.siteTitle ?? "Documentation",
|
|
3181
3241
|
baseUrl: markdownMetadataBaseUrl || url.origin,
|
|
3182
|
-
syncBaseUrl: markdownMetadataBaseUrl ?? null
|
|
3242
|
+
syncBaseUrl: markdownMetadataBaseUrl ?? null,
|
|
3243
|
+
facet,
|
|
3244
|
+
cursor,
|
|
3245
|
+
limit
|
|
3183
3246
|
};
|
|
3184
|
-
if (!query) {
|
|
3185
|
-
const searchResponse = structured ? await performDocsSearchWithMetadata(searchOptions) : [];
|
|
3186
|
-
return new Response(JSON.stringify(searchResponse), { headers: { "Content-Type": "application/json" } });
|
|
3187
|
-
}
|
|
3188
3247
|
const searchStartedAt = Date.now();
|
|
3189
|
-
|
|
3190
|
-
|
|
3248
|
+
let searchResponse;
|
|
3249
|
+
try {
|
|
3250
|
+
searchResponse = facets ? await buildDocsSearchFacets(searchOptions) : structured ? await performDocsSearchWithMetadata(searchOptions) : query ? await performDocsSearch(searchOptions) : [];
|
|
3251
|
+
} catch (error) {
|
|
3252
|
+
const searchError = resolveDocsSearchError(error);
|
|
3253
|
+
if (!searchError) throw error;
|
|
3254
|
+
return Response.json({ error: searchError }, { status: 400 });
|
|
3255
|
+
}
|
|
3256
|
+
if (facets) return Response.json(searchResponse, { headers: { "Cache-Control": "public, max-age=60, stale-while-revalidate=300" } });
|
|
3257
|
+
if (!query) return Response.json(searchResponse);
|
|
3258
|
+
const resultCount = Array.isArray(searchResponse) ? searchResponse.length : "resultCount" in searchResponse ? searchResponse.resultCount : searchResponse.matchedPageCount;
|
|
3191
3259
|
await emitDocsAnalyticsEvent(analytics, {
|
|
3192
3260
|
type: "api_search",
|
|
3193
3261
|
source: "server",
|
|
3194
|
-
url:
|
|
3262
|
+
url: `${url.origin}${url.pathname}`,
|
|
3195
3263
|
path: url.pathname,
|
|
3196
3264
|
locale: ctx.locale,
|
|
3197
3265
|
input: { query },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farming-labs/theme",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.78",
|
|
4
4
|
"description": "Theme package for @farming-labs/docs — layout, provider, MDX components, and styles",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"docs",
|
|
@@ -148,7 +148,7 @@
|
|
|
148
148
|
"tsdown": "^0.20.3",
|
|
149
149
|
"typescript": "^5.9.3",
|
|
150
150
|
"vitest": "^4.1.8",
|
|
151
|
-
"@farming-labs/docs": "0.2.
|
|
151
|
+
"@farming-labs/docs": "0.2.78"
|
|
152
152
|
},
|
|
153
153
|
"peerDependencies": {
|
|
154
154
|
"@farming-labs/docs": ">=0.0.1",
|