@farming-labs/docs 0.2.40 → 0.2.42
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/{agent-WcXCJ4EN.mjs → agent-DXDOMJBw.mjs} +6 -6
- package/dist/{agents-BjTEkCsY.mjs → agents-DjhjZaNP.mjs} +5 -5
- package/dist/analytics-BZEwTK-8.mjs +177 -0
- package/dist/cli/index.mjs +27 -27
- package/dist/client/react.d.mts +45 -0
- package/dist/client/react.mjs +223 -0
- package/dist/{cloud-wcDf1YC0.mjs → cloud-Cbgjl3Pk.mjs} +3 -3
- package/dist/cloud-analytics-Dlk_byos.mjs +132 -0
- package/dist/cloud-ask-ai-Cl-xaV8j.mjs +382 -0
- package/dist/cloud-ask-ai-DcMe6xOf.d.mts +23 -0
- package/dist/{codeblocks-DTlvGTH4.mjs → codeblocks-z9iT794h.mjs} +3 -3
- package/dist/{dev-DxVevOP_.mjs → dev-CBha7knT.mjs} +2 -2
- package/dist/docs-cloud-server.d.mts +70 -0
- package/dist/docs-cloud-server.mjs +310 -0
- package/dist/{doctor-VwhpJct8.mjs → doctor-O9o9kjN8.mjs} +7 -7
- package/dist/{downgrade-ghVFFHKi.mjs → downgrade-7PGER59g.mjs} +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +4 -3
- package/dist/{init-DkcasCws.mjs → init-DAPFsEK8.mjs} +3 -3
- package/dist/{mcp-DfJiBC0f.mjs → mcp-DuCPNHS-.mjs} +4 -4
- package/dist/mcp.d.mts +1 -1
- package/dist/mcp.mjs +3 -2
- package/dist/{package-version-CeNAB4NZ.mjs → package-version-DPQSBBsX.mjs} +1 -1
- package/dist/{review-Bnd4NH9y.mjs → review-lm3dt7yy.mjs} +2 -2
- package/dist/{robots-BrBGgn1w.mjs → robots-DV7u4Ire.mjs} +4 -4
- package/dist/{robots-CVoC0w0i.mjs → robots-XVPs9lVz.mjs} +1 -1
- package/dist/{search-CA3H4Dfv.mjs → search-B6nEkx86.mjs} +4 -4
- package/dist/{search-BuOU4idW.mjs → search-BWuU70B0.mjs} +2 -306
- package/dist/{search-BEe1Gdu7.d.mts → search-DFEhf9-s.d.mts} +1 -1
- package/dist/server.d.mts +5 -23
- package/dist/server.mjs +8 -5
- package/dist/{sitemap-CUtSSoGG.mjs → sitemap-BEiKy4Iy.mjs} +5 -5
- package/dist/{sitemap-server-PLcNxmtk.mjs → sitemap-server-xEHtDUDB.mjs} +2 -382
- package/dist/{types-DKCNILor.d.mts → types-XqGLsmOD.d.mts} +17 -0
- package/dist/{upgrade-aexO-zom.mjs → upgrade-CkdKWRlk.mjs} +2 -2
- package/package.json +21 -1
- /package/dist/{agent-B6szuz_8.mjs → agent-CaOBIVFy.mjs} +0 -0
- /package/dist/{config-De5z-2LK.mjs → config-tiQCZ46q.mjs} +0 -0
- /package/dist/{errors-Dw5gMhEZ.mjs → errors-CW1LnxaQ.mjs} +0 -0
- /package/dist/{review-CJD85JTm.mjs → review-B7goPYUb.mjs} +0 -0
- /package/dist/{templates-BOoV0cIR.mjs → templates-CEcOVbV0.mjs} +0 -0
- /package/dist/{utils-CoHZJ1i4.mjs → utils-D-xTRNuh.mjs} +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { kt as resolveDocsSitemapConfig } from "./agent-B6szuz_8.mjs";
|
|
1
|
+
import { kt as resolveDocsSitemapConfig } from "./agent-CaOBIVFy.mjs";
|
|
3
2
|
import { createRequire } from "node:module";
|
|
4
3
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
5
4
|
import path, { basename, join, relative } from "node:path";
|
|
@@ -959,385 +958,6 @@ function humanizeSegment(value) {
|
|
|
959
958
|
return value.replace(/^\{/, "").replace(/\}$/, "").replace(/^\[\[?\.{3}/, "").replace(/^\[/, "").replace(/\]\]?$/, "").replace(/^\$/, "").replace(/-/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
|
|
960
959
|
}
|
|
961
960
|
|
|
962
|
-
//#endregion
|
|
963
|
-
//#region src/cloud-ask-ai.ts
|
|
964
|
-
const DEFAULT_DOCS_CLOUD_API_BASE_URL = "https://api.farming-labs.dev";
|
|
965
|
-
const DEFAULT_DOCS_CLOUD_API_KEY_ENV = "DOCS_CLOUD_API_KEY";
|
|
966
|
-
const DOCS_CLOUD_PROJECT_ID_ENVS = [
|
|
967
|
-
"PUBLIC_DOCS_CLOUD_PROJECT_ID",
|
|
968
|
-
"DOCS_CLOUD_PROJECT_ID",
|
|
969
|
-
"NEXT_PUBLIC_DOCS_CLOUD_PROJECT_ID"
|
|
970
|
-
];
|
|
971
|
-
const DOCS_CLOUD_API_BASE_URL_ENVS = [
|
|
972
|
-
"DOCS_CLOUD_API_BASE_URL",
|
|
973
|
-
"DOCS_CLOUD_API_URL",
|
|
974
|
-
"PUBLIC_DOCS_CLOUD_URL",
|
|
975
|
-
"NEXT_PUBLIC_DOCS_CLOUD_URL"
|
|
976
|
-
];
|
|
977
|
-
const DOCS_CLOUD_FOOTER_GUARD_CHARS = 256;
|
|
978
|
-
const docsCloudRelevantDocsPattern = /\n{2,}(?:-{3,}|\*{3,}|_{3,})[ \t]*\n{1,3}(?:#{1,6}[ \t]+)?(?:\*\*)?Relevant docs(?:\*\*)?[ \t]*/i;
|
|
979
|
-
const docsCloudThematicBreakPattern = /^[ \t]*(?:-{3,}|\*{3,}|_{3,})[ \t]*$/gm;
|
|
980
|
-
function isPlainObject(value) {
|
|
981
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
982
|
-
}
|
|
983
|
-
function readEnv(name, env) {
|
|
984
|
-
const trimmed = (env?.[name] ?? (typeof process !== "undefined" ? process.env?.[name] : void 0))?.trim();
|
|
985
|
-
return trimmed ? trimmed : void 0;
|
|
986
|
-
}
|
|
987
|
-
function readFirstEnv(names, env) {
|
|
988
|
-
for (const name of names) {
|
|
989
|
-
const value = readEnv(name, env);
|
|
990
|
-
if (value) return value;
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
function resolveDocsCloudApiBaseUrl(env) {
|
|
994
|
-
return (readFirstEnv(DOCS_CLOUD_API_BASE_URL_ENVS, env) ?? DEFAULT_DOCS_CLOUD_API_BASE_URL).replace(/\/+$/, "");
|
|
995
|
-
}
|
|
996
|
-
function resolveDocsCloudProjectId(env) {
|
|
997
|
-
return readFirstEnv(DOCS_CLOUD_PROJECT_ID_ENVS, env);
|
|
998
|
-
}
|
|
999
|
-
function resolveDocsCloudApiKey(cloudConfig, env) {
|
|
1000
|
-
const envName = cloudConfig?.apiKey?.env?.trim() || DEFAULT_DOCS_CLOUD_API_KEY_ENV;
|
|
1001
|
-
return {
|
|
1002
|
-
envName,
|
|
1003
|
-
apiKey: readEnv(envName, env)
|
|
1004
|
-
};
|
|
1005
|
-
}
|
|
1006
|
-
function jsonError(message, status) {
|
|
1007
|
-
return Response.json({ error: message }, { status });
|
|
1008
|
-
}
|
|
1009
|
-
function textFromMessageContent(content) {
|
|
1010
|
-
if (typeof content === "string") return content;
|
|
1011
|
-
if (!Array.isArray(content)) return "";
|
|
1012
|
-
return content.map((part) => {
|
|
1013
|
-
if (typeof part === "string") return part;
|
|
1014
|
-
if (!isPlainObject(part)) return "";
|
|
1015
|
-
if (typeof part.text === "string") return part.text;
|
|
1016
|
-
if (typeof part.content === "string") return part.content;
|
|
1017
|
-
return "";
|
|
1018
|
-
}).filter(Boolean).join("\n");
|
|
1019
|
-
}
|
|
1020
|
-
function lastUserQuestion(messages) {
|
|
1021
|
-
if (!Array.isArray(messages)) return "";
|
|
1022
|
-
return textFromMessageContent([...messages].reverse().find((message) => message?.role === "user")?.content).trim();
|
|
1023
|
-
}
|
|
1024
|
-
function resolveQuestion(body) {
|
|
1025
|
-
return typeof body.question === "string" && body.question.trim() ? body.question.trim() : lastUserQuestion(body.messages);
|
|
1026
|
-
}
|
|
1027
|
-
function shouldStreamResponse(request, body, aiConfig) {
|
|
1028
|
-
if (typeof body.stream === "boolean") return body.stream;
|
|
1029
|
-
if (aiConfig?.stream === false) return false;
|
|
1030
|
-
const accept = request.headers.get("accept")?.toLowerCase();
|
|
1031
|
-
return !accept || accept.includes("text/event-stream") || accept.includes("*/*");
|
|
1032
|
-
}
|
|
1033
|
-
function stripRelevantDocsFooter(content) {
|
|
1034
|
-
return content.replace(new RegExp(`${docsCloudRelevantDocsPattern.source}[\\s\\S]*$`, "i"), "").trimEnd();
|
|
1035
|
-
}
|
|
1036
|
-
function stripMarkdownThematicBreaks(content) {
|
|
1037
|
-
return content.replace(docsCloudThematicBreakPattern, "").replace(/\n{3,}/g, "\n\n").trimEnd();
|
|
1038
|
-
}
|
|
1039
|
-
function cleanDocsCloudAnswer(content) {
|
|
1040
|
-
return stripMarkdownThematicBreaks(stripRelevantDocsFooter(content));
|
|
1041
|
-
}
|
|
1042
|
-
function safeDocsCloudContent(content, final = false) {
|
|
1043
|
-
const footerStart = content.search(docsCloudRelevantDocsPattern);
|
|
1044
|
-
if (footerStart >= 0) return stripMarkdownThematicBreaks(content.slice(0, footerStart));
|
|
1045
|
-
if (final) return cleanDocsCloudAnswer(content);
|
|
1046
|
-
return stripMarkdownThematicBreaks(content.slice(0, Math.max(0, content.length - DOCS_CLOUD_FOOTER_GUARD_CHARS)));
|
|
1047
|
-
}
|
|
1048
|
-
function createOpenAICompatibleSseChunk(content) {
|
|
1049
|
-
return `data: ${JSON.stringify({ choices: [{ delta: { content } }] })}\n\n`;
|
|
1050
|
-
}
|
|
1051
|
-
function createOpenAICompatibleSseResponse(content) {
|
|
1052
|
-
const encoder = new TextEncoder();
|
|
1053
|
-
const stream = new ReadableStream({ start(controller) {
|
|
1054
|
-
if (content) controller.enqueue(encoder.encode(createOpenAICompatibleSseChunk(content)));
|
|
1055
|
-
controller.enqueue(encoder.encode("data: [DONE]\n\n"));
|
|
1056
|
-
controller.close();
|
|
1057
|
-
} });
|
|
1058
|
-
return new Response(stream, { headers: {
|
|
1059
|
-
"Content-Type": "text/event-stream",
|
|
1060
|
-
"Cache-Control": "no-cache, no-transform",
|
|
1061
|
-
Connection: "keep-alive"
|
|
1062
|
-
} });
|
|
1063
|
-
}
|
|
1064
|
-
function openAICompatibleDeltaContent(value) {
|
|
1065
|
-
if (!isPlainObject(value)) return void 0;
|
|
1066
|
-
const firstChoice = Array.isArray(value.choices) ? value.choices[0] : void 0;
|
|
1067
|
-
if (!isPlainObject(firstChoice) || !isPlainObject(firstChoice.delta)) return void 0;
|
|
1068
|
-
return typeof firstChoice.delta.content === "string" ? firstChoice.delta.content : void 0;
|
|
1069
|
-
}
|
|
1070
|
-
function docsCloudStreamContent(value) {
|
|
1071
|
-
if (typeof value === "string") return value;
|
|
1072
|
-
if (!isPlainObject(value)) return void 0;
|
|
1073
|
-
for (const key of [
|
|
1074
|
-
"content",
|
|
1075
|
-
"text",
|
|
1076
|
-
"answer",
|
|
1077
|
-
"delta"
|
|
1078
|
-
]) {
|
|
1079
|
-
const content = value[key];
|
|
1080
|
-
if (typeof content === "string") return content;
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
-
function docsCloudAnswerFromPayload(payload) {
|
|
1084
|
-
if (!isPlainObject(payload)) return "";
|
|
1085
|
-
for (const key of [
|
|
1086
|
-
"answer",
|
|
1087
|
-
"text",
|
|
1088
|
-
"content"
|
|
1089
|
-
]) {
|
|
1090
|
-
const content = payload[key];
|
|
1091
|
-
if (typeof content === "string") return content;
|
|
1092
|
-
}
|
|
1093
|
-
return "";
|
|
1094
|
-
}
|
|
1095
|
-
function createCleanDocsCloudSseResponse(upstream) {
|
|
1096
|
-
if (!upstream.ok || !upstream.body) return new Response(upstream.body, {
|
|
1097
|
-
status: upstream.status,
|
|
1098
|
-
statusText: upstream.statusText,
|
|
1099
|
-
headers: {
|
|
1100
|
-
"Content-Type": upstream.headers.get("Content-Type") ?? "text/event-stream",
|
|
1101
|
-
"Cache-Control": upstream.headers.get("Cache-Control") ?? "no-cache, no-transform",
|
|
1102
|
-
Connection: upstream.headers.get("Connection") ?? "keep-alive"
|
|
1103
|
-
}
|
|
1104
|
-
});
|
|
1105
|
-
const decoder = new TextDecoder();
|
|
1106
|
-
const encoder = new TextEncoder();
|
|
1107
|
-
const stream = new ReadableStream({ async start(controller) {
|
|
1108
|
-
const reader = upstream.body.getReader();
|
|
1109
|
-
let buffer = "";
|
|
1110
|
-
let content = "";
|
|
1111
|
-
let emittedLength = 0;
|
|
1112
|
-
const enqueue = (chunk) => {
|
|
1113
|
-
controller.enqueue(encoder.encode(chunk));
|
|
1114
|
-
};
|
|
1115
|
-
const emitSafeContent = (final = false) => {
|
|
1116
|
-
const safeContent = safeDocsCloudContent(content, final);
|
|
1117
|
-
if (safeContent.length <= emittedLength) return;
|
|
1118
|
-
enqueue(createOpenAICompatibleSseChunk(safeContent.slice(emittedLength)));
|
|
1119
|
-
emittedLength = safeContent.length;
|
|
1120
|
-
};
|
|
1121
|
-
const flushEvent = (event) => {
|
|
1122
|
-
const data = event.split(/\r?\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trim()).filter(Boolean).join("\n").trim();
|
|
1123
|
-
if (!data) return;
|
|
1124
|
-
if (data === "[DONE]") return;
|
|
1125
|
-
try {
|
|
1126
|
-
const parsed = JSON.parse(data);
|
|
1127
|
-
const delta = openAICompatibleDeltaContent(parsed) ?? docsCloudStreamContent(parsed);
|
|
1128
|
-
if (delta) {
|
|
1129
|
-
content += delta;
|
|
1130
|
-
emitSafeContent();
|
|
1131
|
-
}
|
|
1132
|
-
} catch {
|
|
1133
|
-
content += data;
|
|
1134
|
-
emitSafeContent();
|
|
1135
|
-
}
|
|
1136
|
-
};
|
|
1137
|
-
try {
|
|
1138
|
-
while (true) {
|
|
1139
|
-
const { value, done } = await reader.read();
|
|
1140
|
-
if (done) break;
|
|
1141
|
-
buffer += decoder.decode(value, { stream: true });
|
|
1142
|
-
const events = buffer.split(/\r?\n\r?\n/);
|
|
1143
|
-
buffer = events.pop() ?? "";
|
|
1144
|
-
for (const event of events) flushEvent(event);
|
|
1145
|
-
}
|
|
1146
|
-
buffer += decoder.decode();
|
|
1147
|
-
if (buffer.trim()) flushEvent(buffer);
|
|
1148
|
-
} catch {}
|
|
1149
|
-
emitSafeContent(true);
|
|
1150
|
-
enqueue("data: [DONE]\n\n");
|
|
1151
|
-
controller.close();
|
|
1152
|
-
} });
|
|
1153
|
-
return new Response(stream, {
|
|
1154
|
-
status: upstream.status,
|
|
1155
|
-
statusText: upstream.statusText,
|
|
1156
|
-
headers: {
|
|
1157
|
-
"Content-Type": "text/event-stream",
|
|
1158
|
-
"Cache-Control": upstream.headers.get("Cache-Control") ?? "no-cache, no-transform",
|
|
1159
|
-
Connection: upstream.headers.get("Connection") ?? "keep-alive"
|
|
1160
|
-
}
|
|
1161
|
-
});
|
|
1162
|
-
}
|
|
1163
|
-
function analyticsProperties(request) {
|
|
1164
|
-
const userAgent = request.headers.get("user-agent")?.trim();
|
|
1165
|
-
return userAgent ? { userAgent } : {};
|
|
1166
|
-
}
|
|
1167
|
-
function isDocsCloudAskAIProvider(config) {
|
|
1168
|
-
return config?.enabled === true && config.provider === "docs-cloud";
|
|
1169
|
-
}
|
|
1170
|
-
async function createDocsCloudAskAIResponse(request, options = {}) {
|
|
1171
|
-
const config = options.config;
|
|
1172
|
-
const aiConfig = config?.ai;
|
|
1173
|
-
const analytics = config?.analytics;
|
|
1174
|
-
const requestUrl = new URL(request.url);
|
|
1175
|
-
const requestStartedAt = Date.now();
|
|
1176
|
-
const requestProperties = analyticsProperties(request);
|
|
1177
|
-
let body;
|
|
1178
|
-
try {
|
|
1179
|
-
body = await request.json();
|
|
1180
|
-
} catch {
|
|
1181
|
-
await emitDocsAnalyticsEvent(analytics, {
|
|
1182
|
-
type: "api_ai_error",
|
|
1183
|
-
source: "server",
|
|
1184
|
-
url: request.url,
|
|
1185
|
-
path: requestUrl.pathname,
|
|
1186
|
-
locale: options.locale,
|
|
1187
|
-
properties: {
|
|
1188
|
-
...requestProperties,
|
|
1189
|
-
reason: "invalid_json",
|
|
1190
|
-
provider: "docs-cloud",
|
|
1191
|
-
durationMs: Math.max(0, Date.now() - requestStartedAt)
|
|
1192
|
-
}
|
|
1193
|
-
});
|
|
1194
|
-
return jsonError("Invalid JSON body. Expected { messages: [...] }.", 400);
|
|
1195
|
-
}
|
|
1196
|
-
const question = resolveQuestion(body);
|
|
1197
|
-
const messages = Array.isArray(body.messages) ? body.messages : void 0;
|
|
1198
|
-
if (!question) {
|
|
1199
|
-
await emitDocsAnalyticsEvent(analytics, {
|
|
1200
|
-
type: "api_ai_error",
|
|
1201
|
-
source: "server",
|
|
1202
|
-
url: request.url,
|
|
1203
|
-
path: requestUrl.pathname,
|
|
1204
|
-
locale: options.locale,
|
|
1205
|
-
properties: {
|
|
1206
|
-
...requestProperties,
|
|
1207
|
-
reason: "missing_user_message",
|
|
1208
|
-
provider: "docs-cloud",
|
|
1209
|
-
durationMs: Math.max(0, Date.now() - requestStartedAt)
|
|
1210
|
-
}
|
|
1211
|
-
});
|
|
1212
|
-
return jsonError("At least one user message is required.", 400);
|
|
1213
|
-
}
|
|
1214
|
-
const projectId = resolveDocsCloudProjectId(options.env);
|
|
1215
|
-
const { envName, apiKey } = resolveDocsCloudApiKey(config?.cloud, options.env);
|
|
1216
|
-
if (!projectId || !apiKey) {
|
|
1217
|
-
const reason = !projectId ? "missing_docs_cloud_project_id" : "missing_docs_cloud_api_key";
|
|
1218
|
-
await emitDocsAnalyticsEvent(analytics, {
|
|
1219
|
-
type: "api_ai_error",
|
|
1220
|
-
source: "server",
|
|
1221
|
-
url: request.url,
|
|
1222
|
-
path: requestUrl.pathname,
|
|
1223
|
-
locale: options.locale,
|
|
1224
|
-
input: { question },
|
|
1225
|
-
properties: {
|
|
1226
|
-
...requestProperties,
|
|
1227
|
-
reason,
|
|
1228
|
-
provider: "docs-cloud",
|
|
1229
|
-
envName: !apiKey ? envName : void 0,
|
|
1230
|
-
durationMs: Math.max(0, Date.now() - requestStartedAt)
|
|
1231
|
-
}
|
|
1232
|
-
});
|
|
1233
|
-
return jsonError(!projectId ? `Docs Cloud Ask AI is missing ${DOCS_CLOUD_PROJECT_ID_ENVS.join(" or ")}. Add the project id to the deployment environment.` : `Docs Cloud Ask AI is missing ${envName}. Add it to the deployment environment.`, 500);
|
|
1234
|
-
}
|
|
1235
|
-
const stream = shouldStreamResponse(request, body, aiConfig);
|
|
1236
|
-
const apiBaseUrl = resolveDocsCloudApiBaseUrl(options.env);
|
|
1237
|
-
const publicBaseUrl = aiConfig?.docsUrl ?? options.publicBaseUrl ?? requestUrl.origin;
|
|
1238
|
-
const requestedModel = typeof body.model === "string" && body.model.trim() ? body.model.trim() : void 0;
|
|
1239
|
-
await emitDocsAnalyticsEvent(analytics, {
|
|
1240
|
-
type: "api_ai_request",
|
|
1241
|
-
source: "server",
|
|
1242
|
-
url: request.url,
|
|
1243
|
-
path: requestUrl.pathname,
|
|
1244
|
-
locale: options.locale,
|
|
1245
|
-
input: { question },
|
|
1246
|
-
properties: {
|
|
1247
|
-
...requestProperties,
|
|
1248
|
-
provider: "docs-cloud",
|
|
1249
|
-
messageCount: messages?.length,
|
|
1250
|
-
questionLength: question.length,
|
|
1251
|
-
model: requestedModel ?? "docs-cloud"
|
|
1252
|
-
}
|
|
1253
|
-
});
|
|
1254
|
-
let upstream;
|
|
1255
|
-
try {
|
|
1256
|
-
upstream = await (options.fetch ?? fetch)(`${apiBaseUrl}/v1/projects/${encodeURIComponent(projectId)}/knowledge/ask`, {
|
|
1257
|
-
method: "POST",
|
|
1258
|
-
headers: {
|
|
1259
|
-
Accept: stream ? "text/event-stream, application/json" : "application/json",
|
|
1260
|
-
Authorization: `Bearer ${apiKey}`,
|
|
1261
|
-
"Content-Type": "application/json",
|
|
1262
|
-
"X-Docs-Cloud-Public-Base-Url": publicBaseUrl
|
|
1263
|
-
},
|
|
1264
|
-
body: JSON.stringify({
|
|
1265
|
-
messages,
|
|
1266
|
-
question,
|
|
1267
|
-
answerMode: "auto",
|
|
1268
|
-
answerStyle: "public",
|
|
1269
|
-
modelPreference: requestedModel,
|
|
1270
|
-
stream,
|
|
1271
|
-
publicBaseUrl
|
|
1272
|
-
})
|
|
1273
|
-
});
|
|
1274
|
-
} catch {
|
|
1275
|
-
await emitDocsAnalyticsEvent(analytics, {
|
|
1276
|
-
type: "api_ai_error",
|
|
1277
|
-
source: "server",
|
|
1278
|
-
url: request.url,
|
|
1279
|
-
path: requestUrl.pathname,
|
|
1280
|
-
locale: options.locale,
|
|
1281
|
-
input: { question },
|
|
1282
|
-
properties: {
|
|
1283
|
-
...requestProperties,
|
|
1284
|
-
reason: "docs_cloud_fetch_error",
|
|
1285
|
-
provider: "docs-cloud",
|
|
1286
|
-
durationMs: Math.max(0, Date.now() - requestStartedAt)
|
|
1287
|
-
}
|
|
1288
|
-
});
|
|
1289
|
-
return jsonError("Docs Cloud Ask AI request failed.", 502);
|
|
1290
|
-
}
|
|
1291
|
-
if (!upstream.ok) {
|
|
1292
|
-
await upstream.text().catch(() => "");
|
|
1293
|
-
await emitDocsAnalyticsEvent(analytics, {
|
|
1294
|
-
type: "api_ai_error",
|
|
1295
|
-
source: "server",
|
|
1296
|
-
url: request.url,
|
|
1297
|
-
path: requestUrl.pathname,
|
|
1298
|
-
locale: options.locale,
|
|
1299
|
-
input: { question },
|
|
1300
|
-
properties: {
|
|
1301
|
-
...requestProperties,
|
|
1302
|
-
reason: "docs_cloud_error",
|
|
1303
|
-
provider: "docs-cloud",
|
|
1304
|
-
status: upstream.status,
|
|
1305
|
-
durationMs: Math.max(0, Date.now() - requestStartedAt)
|
|
1306
|
-
}
|
|
1307
|
-
});
|
|
1308
|
-
return jsonError(`Docs Cloud Ask AI error (${upstream.status}).`, 502);
|
|
1309
|
-
}
|
|
1310
|
-
await emitDocsAnalyticsEvent(analytics, {
|
|
1311
|
-
type: "api_ai_response",
|
|
1312
|
-
source: "server",
|
|
1313
|
-
url: request.url,
|
|
1314
|
-
path: requestUrl.pathname,
|
|
1315
|
-
locale: options.locale,
|
|
1316
|
-
input: { question },
|
|
1317
|
-
properties: {
|
|
1318
|
-
...requestProperties,
|
|
1319
|
-
provider: "docs-cloud",
|
|
1320
|
-
status: upstream.status,
|
|
1321
|
-
durationMs: Math.max(0, Date.now() - requestStartedAt)
|
|
1322
|
-
}
|
|
1323
|
-
});
|
|
1324
|
-
const contentType = upstream.headers.get("Content-Type") ?? "";
|
|
1325
|
-
if (stream && contentType.includes("text/event-stream")) return createCleanDocsCloudSseResponse(upstream);
|
|
1326
|
-
const upstreamBody = await upstream.text();
|
|
1327
|
-
let payload;
|
|
1328
|
-
let answer = upstreamBody;
|
|
1329
|
-
try {
|
|
1330
|
-
payload = JSON.parse(upstreamBody);
|
|
1331
|
-
answer = docsCloudAnswerFromPayload(payload) || answer;
|
|
1332
|
-
} catch {}
|
|
1333
|
-
const cleanAnswer = cleanDocsCloudAnswer(answer);
|
|
1334
|
-
if (stream) return createOpenAICompatibleSseResponse(cleanAnswer);
|
|
1335
|
-
return Response.json(isPlainObject(payload) ? {
|
|
1336
|
-
...payload,
|
|
1337
|
-
answer: cleanAnswer
|
|
1338
|
-
} : { answer: cleanAnswer });
|
|
1339
|
-
}
|
|
1340
|
-
|
|
1341
961
|
//#endregion
|
|
1342
962
|
//#region src/prompt-utils.ts
|
|
1343
963
|
const require = createRequire(import.meta.url);
|
|
@@ -1513,4 +1133,4 @@ function readDocsSitemapManifest(rootDir, sitemap) {
|
|
|
1513
1133
|
}
|
|
1514
1134
|
|
|
1515
1135
|
//#endregion
|
|
1516
|
-
export {
|
|
1136
|
+
export { resolveApiReferenceOpenApiDiscovery as C, resolveApiReferenceConfig as S, remarkCodeGroup as T, buildApiReferenceOpenApiDocument as _, DEFAULT_PROMPT_PROVIDER_TEMPLATES as a, buildApiReferenceScalarCss as b, resolvePromptProviderChoices as c, serializeDocsIconRegistry as d, serializeOpenDocsProvider as f, buildApiReferenceHtmlDocumentAsync as g, buildApiReferenceHtmlDocument as h, DEFAULT_OPEN_DOCS_TARGET as i, sanitizePromptText as l, DEFAULT_API_REFERENCE_OPENAPI_ROUTE as m, DEFAULT_OPEN_DOCS_PROMPT as n, normalizePromptProviderName as o, serializeOpenDocsProviders as p, DEFAULT_OPEN_DOCS_PROVIDER_IDS as r, parsePromptStringArray as s, readDocsSitemapManifest as t, serializeDocsIcon as u, buildApiReferenceOpenApiDocumentAsync as v, resolveApiReferenceRenderer as w, isApiReferenceOpenApiRequest as x, buildApiReferencePageTitle as y };
|
|
@@ -766,6 +766,12 @@ interface DocsAnalyticsConfig {
|
|
|
766
766
|
includeInputs?: boolean;
|
|
767
767
|
/** Callback fired for every emitted event. */
|
|
768
768
|
onEvent?: (event: DocsAnalyticsEvent) => void | Promise<void>;
|
|
769
|
+
/**
|
|
770
|
+
* Forward events to Docs Cloud when project env vars are available.
|
|
771
|
+
*
|
|
772
|
+
* @default true
|
|
773
|
+
*/
|
|
774
|
+
cloud?: boolean;
|
|
769
775
|
}
|
|
770
776
|
type DocsTelemetryFramework = "next" | "tanstack-start" | "sveltekit" | "astro" | "nuxt" | "mcp" | (string & {});
|
|
771
777
|
type DocsTelemetryEventType = "project_detected" | "agent_surface_used" | "mcp_request" | "mcp_tool_used" | (string & {});
|
|
@@ -873,6 +879,17 @@ interface DocsCloudConfig {
|
|
|
873
879
|
enabled?: boolean;
|
|
874
880
|
/** API key lookup used by `docs deploy` and other cloud CLI commands. */
|
|
875
881
|
apiKey?: DocsCloudApiKeyConfig;
|
|
882
|
+
/**
|
|
883
|
+
* Same-origin route for the generated Docs API handler.
|
|
884
|
+
*
|
|
885
|
+
* Next.js layouts use this as the default client analytics proxy when no
|
|
886
|
+
* hosted analytics endpoint env is configured. Set it when the route is
|
|
887
|
+
* mounted somewhere other than `/api/docs`, or when a deployment uses a
|
|
888
|
+
* public base path.
|
|
889
|
+
*
|
|
890
|
+
* @default "/api/docs"
|
|
891
|
+
*/
|
|
892
|
+
apiRoute?: string;
|
|
876
893
|
/** Legacy hosted preview deployment settings. Prefer `deploy` in new configs. */
|
|
877
894
|
preview?: DocsCloudPreviewConfig;
|
|
878
895
|
/** Generated docs publishing settings. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as fileExists, o as exec } from "./utils-
|
|
2
|
-
import { a as getPackagesForFramework, c as resolveDocsPackageManager, i as frameworkFromPreset, l as validateUpgradeVersion, n as PRESETS, o as presetFromFramework, r as buildDocsPackageInstallCommand, s as resolveDocsPackageFramework, t as PACKAGES_BY_FRAMEWORK } from "./package-version-
|
|
1
|
+
import { c as fileExists, o as exec } from "./utils-D-xTRNuh.mjs";
|
|
2
|
+
import { a as getPackagesForFramework, c as resolveDocsPackageManager, i as frameworkFromPreset, l as validateUpgradeVersion, n as PRESETS, o as presetFromFramework, r as buildDocsPackageInstallCommand, s as resolveDocsPackageFramework, t as PACKAGES_BY_FRAMEWORK } from "./package-version-DPQSBBsX.mjs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import pc from "picocolors";
|
|
5
5
|
import * as p from "@clack/prompts";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farming-labs/docs",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.42",
|
|
4
4
|
"description": "Modern, flexible MDX-based docs framework — core types, config, and CLI",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"docs",
|
|
@@ -30,6 +30,16 @@
|
|
|
30
30
|
"import": "./dist/server.mjs",
|
|
31
31
|
"default": "./dist/server.mjs"
|
|
32
32
|
},
|
|
33
|
+
"./cloud/server": {
|
|
34
|
+
"types": "./dist/docs-cloud-server.d.mts",
|
|
35
|
+
"import": "./dist/docs-cloud-server.mjs",
|
|
36
|
+
"default": "./dist/docs-cloud-server.mjs"
|
|
37
|
+
},
|
|
38
|
+
"./client/react": {
|
|
39
|
+
"types": "./dist/client/react.d.mts",
|
|
40
|
+
"import": "./dist/client/react.mjs",
|
|
41
|
+
"default": "./dist/client/react.mjs"
|
|
42
|
+
},
|
|
33
43
|
"./mcp": {
|
|
34
44
|
"types": "./dist/mcp.d.mts",
|
|
35
45
|
"import": "./dist/mcp.mjs",
|
|
@@ -46,8 +56,18 @@
|
|
|
46
56
|
"picocolors": "^1.1.1",
|
|
47
57
|
"zod": "^4.3.6"
|
|
48
58
|
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"react": ">=19.2.0"
|
|
61
|
+
},
|
|
62
|
+
"peerDependenciesMeta": {
|
|
63
|
+
"react": {
|
|
64
|
+
"optional": true
|
|
65
|
+
}
|
|
66
|
+
},
|
|
49
67
|
"devDependencies": {
|
|
50
68
|
"@types/node": "^22.10.0",
|
|
69
|
+
"@types/react": "^19.2.2",
|
|
70
|
+
"react": "^19.2.0",
|
|
51
71
|
"tsdown": "^0.20.3",
|
|
52
72
|
"typescript": "^5.9.3",
|
|
53
73
|
"vitest": "^4.1.8"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|