PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.9.5
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.9.5
4.9.5 4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 All 203 releases
betterdocs / react-src / gutenberg / write-with-ai / api.js

api.js in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 4.9.5, at react-src/gutenberg/write-with-ai/api.js

118 lines 4.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 // ===== write-with-ai/api.js — REST client for betterdocs/v1/write-with-ai =====
2
3 import apiFetch from "@wordpress/api-fetch";
4 import { __ } from "@wordpress/i18n";
5
6 export const getConfig = () =>
7 (typeof window !== "undefined" && window.betterdocsWriteWithAI) || {};
8
9 // Normalize a thrown/responded error into the { code, message } shape the
10 // PreviewAccept Banner understands.
11 const toError = (e) => {
12 if (e && e.code && e.message) return { code: e.code, message: e.message };
13 const message = (e && e.message) || __("Failed to reach the AI service. Please try again.", "betterdocs");
14 let code = "empty";
15 if (/rate|429/i.test(message)) code = "rate_limit";
16 else if (/time/i.test(message)) code = "timeout";
17 return { code, message };
18 };
19
20 // POST one action to the endpoint. Resolves with the `data` object on success,
21 // rejects with { code, message } on failure.
22 export const callWriteWithAI = async (action, payload = {}) => {
23 const config = getConfig();
24 if (!config.rest_url) {
25 throw { code: "missing_key", message: __("Write with AI is not properly initialized.", "betterdocs") };
26 }
27
28 try {
29 const response = await apiFetch({
30 url: config.rest_url,
31 method: "POST",
32 headers: { "X-WP-Nonce": config.rest_nonce },
33 data: { action, post_id: config.post_id, ...payload },
34 });
35
36 if (response && response.success && response.data) {
37 return response.data;
38 }
39 const message = (response && response.message) || __("Unexpected response from the server.", "betterdocs");
40 throw { code: "empty", message };
41 } catch (e) {
42 throw toError(e);
43 }
44 };
45
46 // POST one action with an uploaded file (multipart/form-data) to the same
47 // endpoint — used by the "From Attachment" source. apiFetch sends the FormData
48 // as-is (no JSON encoding) and still attaches the REST nonce. Arrays are sent as
49 // repeated `key[]` fields so the PHP side reads them as arrays.
50 export const callWriteWithAIMultipart = async (action, fields = {}, file) => {
51 const config = getConfig();
52 if (!config.rest_url) {
53 throw { code: "missing_key", message: __("Write with AI is not properly initialized.", "betterdocs") };
54 }
55
56 const form = new FormData();
57 form.append("action", action);
58 form.append("post_id", config.post_id || 0);
59 Object.entries(fields).forEach(([key, value]) => {
60 if (Array.isArray(value)) {
61 value.forEach((item) => form.append(`${key}[]`, item));
62 } else if (value !== undefined && value !== null) {
63 form.append(key, value);
64 }
65 });
66 if (file) {
67 form.append("file", file, file.name);
68 }
69
70 try {
71 const response = await apiFetch({
72 url: config.rest_url,
73 method: "POST",
74 headers: { "X-WP-Nonce": config.rest_nonce },
75 body: form,
76 });
77
78 if (response && response.success && response.data) {
79 return response.data;
80 }
81 const message = (response && response.message) || __("Unexpected response from the server.", "betterdocs");
82 throw { code: "empty", message };
83 } catch (e) {
84 throw toError(e);
85 }
86 };
87
88 // Ask betterdocs/v1/ai-suggest-terms for AI-suggested terms of one taxonomy,
89 // based on the freshly generated doc. Resolves with the suggestions array
90 // ([{ name, term_id, is_new }]); a disabled suite / missing key / upstream
91 // failure is non-fatal here — it just yields no suggestions for the taxonomy.
92 export const suggestTerms = async ({ taxonomy, content, title }) => {
93 const config = getConfig();
94 if (!config.rest_suggest_url) return [];
95
96 try {
97 const response = await apiFetch({
98 url: config.rest_suggest_url,
99 method: "POST",
100 headers: { "X-WP-Nonce": config.rest_nonce },
101 data: {
102 taxonomy,
103 post_id: config.post_id,
104 content,
105 title,
106 max_suggestions: 6,
107 },
108 });
109
110 if (response && response.success && response.data && Array.isArray(response.data.suggestions)) {
111 return response.data.suggestions;
112 }
113 return [];
114 } catch (e) {
115 return [];
116 }
117 };
118