PluginProbe
Extendify / 1.17.1
Extendify v1.17.1
3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 0.7.0 All 126 releases
extendify / src / Launch / api / DataApi.js

DataApi.js in Extendify 1.17.1, at src/Launch/api/DataApi.js

295 lines 7.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { PATTERNS_HOST, AI_HOST, IMAGES_HOST } from '@constants';
2 import { getHeadersAndFooters } from '@launch/api/WPApi';
3 import { Axios as api } from '@launch/api/axios';
4 import { useUserSelectionStore } from '@launch/state/user-selections';
5
6 // Optionally add items to request body
7 const allowList = [
8 'partnerId',
9 'devbuild',
10 'version',
11 'siteId',
12 'wpLanguage',
13 'wpVersion',
14 'siteProfile',
15 ];
16
17 const extraBody = {
18 ...Object.fromEntries(
19 Object.entries(window.extSharedData).filter(([key]) =>
20 allowList.includes(key),
21 ),
22 ),
23 };
24
25 const fetchTemplates = async (type, siteType, otherData = {}) => {
26 const { showLocalizedCopy, allowedPlugins } = window.extSharedData;
27 const { goals, getGoalsPlugins } = useUserSelectionStore.getState();
28 const plugins = getGoalsPlugins();
29 const otherDataProcessed = Object.entries(otherData).reduce(
30 (result, [key, value]) => {
31 if (value == null) result;
32 return {
33 ...result,
34 [key]: typeof value === 'object' ? JSON.stringify(value) : value,
35 };
36 },
37 {},
38 );
39
40 const res = await fetch(`${PATTERNS_HOST}/api/${type}-templates`, {
41 method: 'POST',
42 headers: { 'Content-Type': 'application/json' },
43 body: JSON.stringify({
44 ...extraBody,
45 siteType: siteType?.slug,
46 goals: JSON.stringify(goals?.length ? goals : []),
47 plugins: JSON.stringify(plugins?.length ? plugins : []),
48 showLocalizedCopy: !!showLocalizedCopy,
49 allowedPlugins: JSON.stringify(allowedPlugins ?? []),
50 ...otherDataProcessed,
51 }),
52 });
53
54 if (!res.ok) throw new Error('Bad response from server');
55
56 return await res.json();
57 };
58
59 export const getHomeTemplates = async ({
60 siteType,
61 siteStructure,
62 siteProfile,
63 siteStrings,
64 siteImages,
65 siteStyles,
66 goals,
67 }) => {
68 const styles = await fetchTemplates('home', siteType, {
69 siteStructure,
70 siteProfile,
71 siteStrings,
72 siteImages,
73 siteStyles,
74 goals,
75 });
76 const { headers, footers } = await getHeadersAndFooters();
77 if (!styles?.length) {
78 throw new Error('Could not get styles');
79 }
80 return styles.map((template, index) => {
81 // Cycle through the headers and footers
82 const header = headers[index % headers.length];
83 const footer = footers[index % footers.length];
84 return {
85 ...template,
86 headerCode: header?.content?.raw?.trim() ?? '',
87 footerCode: footer?.content?.raw?.trim() ?? '',
88 };
89 });
90 };
91
92 export const getPageTemplates = async ({
93 siteType,
94 siteStructure,
95 siteStrings,
96 siteImages,
97 siteStyle,
98 }) => {
99 const { siteInformation, siteProfile } = useUserSelectionStore.getState();
100 const pages = await fetchTemplates('page', siteType, {
101 siteInformation,
102 siteStructure,
103 siteStrings,
104 siteImages,
105 siteStyle,
106 siteProfile,
107 });
108 if (!pages?.recommended) {
109 throw new Error('Could not get pages');
110 }
111 return {
112 recommended: pages.recommended.map(({ slug, ...rest }) => ({
113 ...rest,
114 slug,
115 id: slug,
116 })),
117 optional: pages.optional.map(({ slug, ...rest }) => ({
118 ...rest,
119 slug,
120 id: slug,
121 })),
122 };
123 };
124
125 export const getGoals = async ({ title, siteTypeSlug, siteProfile }) => {
126 const goals = await api.get('launch/goals', {
127 params: {
128 title,
129 site_type: siteTypeSlug,
130 site_profile: siteProfile,
131 },
132 });
133 if (!goals?.data?.length) {
134 throw new Error('Could not get goals');
135 }
136 return goals.data;
137 };
138
139 export const generateCustomPatterns = async (page, userState, siteProfile) => {
140 const res = await fetch(`${AI_HOST}/api/patterns`, {
141 method: 'POST',
142 headers: { 'Content-Type': 'application/json' },
143 body: JSON.stringify({
144 ...extraBody,
145 page,
146 userState,
147 siteProfile,
148 }),
149 });
150
151 if (!res.ok) throw new Error('Bad response from server');
152 return await res.json();
153 };
154
155 export const getLinkSuggestions = async (pageContent, availablePages) => {
156 const abort = new AbortController();
157 const timeout = setTimeout(() => abort.abort(), 10000);
158 const { siteType } = useUserSelectionStore.getState();
159 try {
160 const res = await fetch(`${AI_HOST}/api/link-pages`, {
161 method: 'POST',
162 headers: { 'Content-Type': 'application/json' },
163 body: JSON.stringify({
164 ...extraBody,
165 siteType: siteType?.slug,
166 pageContent,
167 availablePages,
168 }),
169 signal: abort.signal,
170 });
171 if (!res.ok) throw new Error('Bad response from server');
172 return await res.json();
173 } finally {
174 clearTimeout(timeout);
175 }
176 };
177
178 export const pingServer = () => api.get('launch/ping');
179
180 export const getSiteProfile = async ({ title, description }) => {
181 const url = `${AI_HOST}/api/site-profile`;
182 const method = 'POST';
183 const headers = { 'Content-Type': 'application/json' };
184 const body = JSON.stringify({
185 ...extraBody,
186 title,
187 description,
188 });
189 const fallback = {
190 aiSiteType: null,
191 aiSiteCategory: null,
192 aiDescription: null,
193 aiKeywords: [],
194 };
195 let response;
196 try {
197 response = await fetch(url, { method, headers, body });
198 } catch (error) {
199 // try one more time
200 response = await fetch(url, { method, headers, body });
201 }
202 if (!response.ok) return fallback;
203 let data;
204 try {
205 data = await response.json();
206 } catch (error) {
207 return fallback;
208 }
209 return data?.aiSiteType ? data : fallback;
210 };
211
212 export const getSiteStrings = async (siteProfile) => {
213 const url = `${AI_HOST}/api/site-strings`;
214 const method = 'POST';
215 const headers = { 'Content-Type': 'application/json' };
216 const body = JSON.stringify({ ...extraBody, siteProfile });
217 const fallback = { aiHeaders: [], aiBlogTitles: [] };
218 let response;
219 try {
220 response = await fetch(url, { method, headers, body });
221 } catch (error) {
222 // try one more time
223 response = await fetch(url, { method, headers, body });
224 }
225 if (!response.ok) return fallback;
226 let data;
227 try {
228 data = await response.json();
229 } catch (error) {
230 return fallback;
231 }
232 return data?.aiHeaders ? data : fallback;
233 };
234
235 export const getSiteImages = async (siteProfile) => {
236 const { aiSiteType, aiSiteCategory, aiDescription, aiKeywords } = siteProfile;
237 const { siteInformation } = useUserSelectionStore.getState();
238 const search = new URLSearchParams({
239 aiSiteType,
240 aiSiteCategory,
241 aiDescription,
242 aiKeywords,
243 ...extraBody,
244 });
245 if (siteInformation?.title) search.append('title', siteInformation.title);
246 const url = `${IMAGES_HOST}/api/search?${search}`;
247 const method = 'GET';
248 const headers = { 'Content-Type': 'application/json' };
249 const fallback = { siteImages: [] };
250 let response;
251 try {
252 response = await fetch(url, { method, headers });
253 } catch (error) {
254 // try one more time
255 response = await fetch(url, { method, headers });
256 }
257 if (!response.ok) return fallback;
258 let data;
259 try {
260 data = await response.json();
261 } catch (error) {
262 return fallback;
263 }
264 return data?.siteImages ? data : fallback;
265 };
266
267 export const getSiteStyles = async ({ title, siteProfile }) => {
268 const request = new Request(`${AI_HOST}/api/styles`, {
269 method: 'POST',
270 headers: { 'Content-Type': 'application/json' },
271 body: JSON.stringify({ ...extraBody, title, siteProfile }),
272 });
273
274 let response;
275
276 try {
277 response = await fetch(request);
278 } catch (error) {
279 // try one more time
280 response = await fetch(request);
281 }
282
283 const fallback = [];
284
285 if (!response.ok) {
286 return fallback;
287 }
288
289 try {
290 return await response.json();
291 } catch (_) {
292 return fallback;
293 }
294 };
295