PluginProbe
Extendify / 3.1.2
Extendify v3.1.2
3.2.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 All 127 releases
extendify / src / AutoLaunch / fetchers / get-design-build.js

get-design-build.js in Extendify 3.1.2, at src/AutoLaunch/fetchers/get-design-build.js

136 lines 4.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { uploadLogo } from '@auto-launch/fetchers/get-logo';
2 import { getThemeVariation } from '@auto-launch/fetchers/get-variation';
3 import {
4 getDesignBuildShape,
5 getLogoShape,
6 getPluginsShape,
7 getStyleShape,
8 } from '@auto-launch/fetchers/shape';
9 import {
10 fetchWithTimeout,
11 retryTwice,
12 setStatus,
13 } from '@auto-launch/functions/helpers';
14 import { updateOption } from '@auto-launch/functions/wp';
15 import { useLaunchDataStore } from '@auto-launch/state/launch-data';
16 import { AI_HOST } from '@constants';
17 import { digest } from '@shared/api/digest';
18 import { __ } from '@wordpress/i18n';
19 import { mutate } from 'swr';
20
21 const fallback = null;
22 const headers = { 'Content-Type': 'application/json' };
23
24 export const handleDesignBuild = async ({ urlParams }) => {
25 const buildId = urlParams?.['build-id'];
26 if (!buildId) return fallback;
27
28 // translators: this is for a action log UI. Keep it short
29 setStatus(__('Loading your design', 'extendify-local'));
30
31 const url = `${AI_HOST}/api/design/${encodeURIComponent(buildId)}`;
32 const response = await retryTwice(() =>
33 fetchWithTimeout(url, { headers }),
34 ).catch((error) => {
35 return { ok: false, statusText: error.message, status: 0 };
36 });
37
38 if (!response?.ok) {
39 digest({
40 error: {
41 message: response.statusText,
42 name: 'FetchError',
43 status: response.status,
44 },
45 details: { source: 'auto-launch', caller: 'handleDesignBuild' },
46 });
47 return fallback;
48 }
49
50 try {
51 const parsed = getDesignBuildShape.parse(await response.json());
52
53 // Stash the site profile
54 const profile = parsed.siteProfile;
55 await updateOption('extendify_site_profile', JSON.stringify(profile));
56 mutate('siteProfile', { siteProfile: profile }, false);
57
58 // Stash the site style and variation
59 const style = parsed.siteStyle;
60 const fonts =
61 style.fonts?.heading || style.fonts?.body ? style.fonts : null;
62 const variation = await getThemeVariation(
63 { slug: style.colorPalette, fonts },
64 { fallback: true },
65 );
66 const siteStyle = { ...style, variation };
67 await updateOption('extendify_site_style', siteStyle);
68 await updateOption('extendify_animation_settings', {
69 type: style.animation ?? 'fade',
70 speed: 'medium',
71 });
72 mutate('siteStyle', getStyleShape.parse({ siteStyle }), false);
73
74 // Stash the plugins
75 const sitePlugins = parsed.selectedPlugins;
76 mutate('sitePlugins', getPluginsShape.parse({ sitePlugins }), false);
77
78 // Stash the logo
79 await uploadLogo(parsed.logoUrl);
80 mutate('siteLogo', getLogoShape.parse({ logoUrl: parsed.logoUrl }), false);
81
82 const designBuild = { buildId, ...parsed, siteProfile: profile, siteStyle };
83 // Spreading it here sets it for other state values we override
84 return { designBuild, ...designBuild };
85 } catch (e) {
86 digest({
87 error: e,
88 details: { source: 'auto-launch', caller: 'handleDesignBuild::parsing' },
89 });
90 console.error('handleDesignBuild:', e);
91 // Drop the build-id so downstream checks (e.g. skipDescription) fallback
92 useLaunchDataStore.setState((s) => ({
93 urlParams: { ...s.urlParams, 'build-id': '' },
94 }));
95 return fallback;
96 }
97 };
98
99 // Prepend the design build hero; flagged so it skips content regeneration.
100 export const applyDesignBuildHero = (patterns, designBuild) => {
101 if (!designBuild?.patternCode) return patterns;
102 return [
103 {
104 name: designBuild.patternId,
105 code: designBuild.patternCode,
106 patternTypes: ['hero-header'],
107 contentGenerated: true,
108 },
109 ...patterns,
110 ];
111 };
112
113 // Reorder pages to match the design build's page order; extras fall to the end.
114 export const applyDesignBuildOrder = (pages, designBuild) => {
115 const order = designBuild?.pages?.map((p) => p.slug) ?? [];
116 if (!order.length) return pages;
117 return [
118 ...order.map((slug) => pages.find((t) => t.slug === slug)).filter(Boolean),
119 ...pages.filter((t) => !order.includes(t.slug)),
120 ];
121 };
122
123 // Tag non-hero patterns with their aligned design build page slug/name.
124 // For single-page sites mainly
125 export const applyDesignBuildNav = (patterns, designBuild) => {
126 const pages = designBuild?.pages ?? [];
127 if (!pages.length) return patterns;
128 let i = 0;
129 return patterns.map((pattern) => {
130 if (pattern.patternTypes?.includes('hero-header')) return pattern;
131 const page = pages[i++];
132 if (!page) return pattern;
133 return { ...pattern, navSlug: page.slug, navLabel: page.name };
134 });
135 };
136