@lightspeed/crane 1.4.2 → 2.0.1
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/CHANGELOG.md +51 -0
- package/UPGRADE.md +19 -0
- package/dist/app.d.mts +1 -1028
- package/dist/app.d.ts +1 -1028
- package/dist/app.mjs +1 -1
- package/dist/cli.mjs +20 -7
- package/package.json +4 -3
- package/template/footers/example-footer/ExampleFooter.vue +1 -1
- package/template/footers/example-footer/client.ts +2 -1
- package/template/footers/example-footer/component/LegalLinks.vue +1 -1
- package/template/footers/example-footer/component/MadeWith.vue +1 -1
- package/template/footers/example-footer/component/ReportAbuse.vue +1 -1
- package/template/footers/example-footer/entity/color.ts +2 -2
- package/template/footers/example-footer/server.ts +2 -1
- package/template/headers/example-header/client.ts +2 -1
- package/template/headers/example-header/component/Account.vue +1 -1
- package/template/headers/example-header/component/Cart.vue +1 -1
- package/template/headers/example-header/component/CategoriesDropdown.vue +1 -1
- package/template/headers/example-header/component/Logo.vue +1 -1
- package/template/headers/example-header/component/NavigationMenu.vue +1 -1
- package/template/headers/example-header/component/SearchForm.vue +1 -1
- package/template/headers/example-header/server.ts +2 -1
- package/template/index.d.ts +1 -1
- package/template/layouts/catalog/example-catalog/Main.vue +1 -1
- package/template/layouts/catalog/example-catalog/slots/custom-bottom-bar/client.ts +2 -1
- package/template/layouts/catalog/example-catalog/slots/custom-bottom-bar/server.ts +2 -1
- package/template/layouts/category/example-category/Main.vue +1 -1
- package/template/layouts/category/example-category/settings/content.ts +1 -1
- package/template/layouts/category/example-category/settings/design.ts +1 -1
- package/template/layouts/product/example-product/Main.vue +1 -1
- package/template/layouts/product/example-product/settings/content.ts +1 -1
- package/template/layouts/product/example-product/settings/design.ts +1 -1
- package/template/package.json +6 -3
- package/template/page-templates/example-template/pages/catalog.ts +1 -1
- package/template/page-templates/example-template/pages/category.ts +1 -1
- package/template/page-templates/example-template/pages/product.ts +1 -1
- package/template/preview/sections/preview.html +1 -1
- package/template/preview/shared/api-routes.ts +515 -41
- package/template/preview/shared/mock.ts +43 -41
- package/template/preview/shared/preview.ts +220 -123
- package/template/preview/shared/utils.ts +209 -62
- package/template/preview/ssr-server.ts +430 -0
- package/template/preview/vite.config.js +76 -75
- package/template/reference/sections/about-us/AboutUs.vue +1 -1
- package/template/reference/sections/about-us/client.ts +1 -1
- package/template/reference/sections/about-us/component/Image.vue +1 -1
- package/template/reference/sections/about-us/component/Stats.vue +2 -2
- package/template/reference/sections/about-us/component/Title.vue +1 -1
- package/template/reference/sections/about-us/server.ts +1 -1
- package/template/reference/sections/about-us/util/visibility-provider.ts +1 -1
- package/template/reference/sections/featured-products/FeaturedProducts.vue +65 -0
- package/template/reference/sections/featured-products/assets/arrow.svg +3 -0
- package/template/reference/sections/featured-products/assets/custom_section_showcase_1_preview.png +0 -0
- package/template/reference/sections/featured-products/client.ts +6 -0
- package/template/reference/sections/featured-products/component/ProductItem.vue +71 -0
- package/template/reference/sections/featured-products/component/Title.vue +31 -0
- package/template/reference/sections/featured-products/entity/color.ts +4 -0
- package/template/reference/sections/featured-products/server.ts +6 -0
- package/template/reference/sections/featured-products/settings/content.ts +14 -0
- package/template/reference/sections/featured-products/settings/design.ts +33 -0
- package/template/reference/sections/featured-products/settings/translations.ts +24 -0
- package/template/reference/sections/featured-products/showcases/1.ts +28 -0
- package/template/reference/sections/featured-products/showcases/translations.ts +16 -0
- package/template/reference/sections/featured-products/type.ts +5 -0
- package/template/reference/sections/intro-slider/IntroSlider.vue +1 -1
- package/template/reference/sections/intro-slider/client.ts +2 -1
- package/template/reference/sections/intro-slider/component/Slider.vue +8 -2
- package/template/reference/sections/intro-slider/component/Title.vue +1 -1
- package/template/reference/sections/intro-slider/entity/color.ts +2 -2
- package/template/reference/sections/intro-slider/server.ts +2 -1
- package/template/reference/sections/tag-lines/TagLines.vue +1 -1
- package/template/reference/sections/tag-lines/client.ts +2 -1
- package/template/reference/sections/tag-lines/component/SectionImage.vue +1 -1
- package/template/reference/sections/tag-lines/component/Title.vue +1 -1
- package/template/reference/sections/tag-lines/composables/highlighted-text-image-list.ts +4 -3
- package/template/reference/sections/tag-lines/server.ts +2 -1
- package/template/reference/sections/trending-categories/TrendingCategories.vue +70 -0
- package/template/reference/sections/trending-categories/assets/arrow.svg +3 -0
- package/template/reference/sections/trending-categories/assets/custom_section_showcase_1_preview.png +0 -0
- package/template/reference/sections/trending-categories/client.ts +6 -0
- package/template/reference/sections/trending-categories/component/CategoryItem.vue +62 -0
- package/template/reference/sections/trending-categories/component/Title.vue +32 -0
- package/template/reference/sections/trending-categories/entity/color.ts +4 -0
- package/template/reference/sections/trending-categories/server.ts +6 -0
- package/template/reference/sections/trending-categories/settings/content.ts +14 -0
- package/template/reference/sections/trending-categories/settings/design.ts +33 -0
- package/template/reference/sections/trending-categories/settings/translations.ts +24 -0
- package/template/reference/sections/trending-categories/showcases/1.ts +36 -0
- package/template/reference/sections/trending-categories/showcases/translations.ts +22 -0
- package/template/reference/sections/trending-categories/type.ts +5 -0
- package/template/reference/shared/components/Button.vue +1 -1
- package/template/reference/shared/utils/styles.ts +1 -0
- package/template/reference/templates/reference-template-apparel/pages/catalog.ts +1 -1
- package/template/reference/templates/reference-template-apparel/pages/category.ts +1 -1
- package/template/reference/templates/reference-template-apparel/pages/home.ts +10 -0
- package/template/reference/templates/reference-template-apparel/pages/product.ts +1 -1
- package/template/reference/templates/reference-template-bike/pages/catalog.ts +1 -1
- package/template/reference/templates/reference-template-bike/pages/category.ts +1 -1
- package/template/reference/templates/reference-template-bike/pages/home.ts +10 -0
- package/template/reference/templates/reference-template-bike/pages/product.ts +1 -1
- package/template/sections/example-section/ExampleSection.vue +8 -1
- package/template/sections/example-section/client.ts +2 -1
- package/template/sections/example-section/component/button/Button.vue +1 -1
- package/template/sections/example-section/component/image/Image.vue +1 -1
- package/template/sections/example-section/component/image/ImagesGrid.vue +1 -1
- package/template/sections/example-section/component/selectbox/Selectbox.vue +1 -1
- package/template/sections/example-section/component/title/Title.vue +1 -1
- package/template/sections/example-section/component/toggle/Toggle.vue +1 -1
- package/template/sections/example-section/entity/color.ts +2 -2
- package/template/sections/example-section/server.ts +2 -1
- package/template/sections/example-section/settings/translations.ts +1 -1
- package/template/sections/example-section/showcases/1.ts +2 -22
- package/template/sections/example-section/showcases/2.ts +2 -22
- package/template/sections/example-section/showcases/3.ts +2 -22
- package/template/sections/example-section/showcases/translations.ts +11 -149
- package/template/shared/components/LanguageSelector.vue +1 -1
- package/template/shared/translation.ts +16 -0
- package/template/shared/utils.ts +3 -1
- package/template/tsconfig.json +1 -0
- package/types.d.ts +6 -457
|
@@ -1,28 +1,80 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
|
|
5
|
+
import { getShowcaseState } from './preview';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Renders a server.js module by directly calling the SSR server.
|
|
9
|
+
* Returns HTML directly from the SSR server.
|
|
10
|
+
*/
|
|
11
|
+
export async function renderServerModule(
|
|
12
|
+
modulePath: string,
|
|
13
|
+
context?: unknown,
|
|
14
|
+
data?: unknown,
|
|
15
|
+
): Promise<string> {
|
|
16
|
+
try {
|
|
17
|
+
// Get SSR server port from environment variable
|
|
18
|
+
const ssrPort = process.env.PREVIEW_SSR_PORT || 3001;
|
|
19
|
+
const ssrUrl = `http://localhost:${ssrPort}/load-server-module`;
|
|
20
|
+
|
|
21
|
+
const response = await fetch(ssrUrl, {
|
|
22
|
+
method: 'POST',
|
|
23
|
+
headers: { 'Content-Type': 'application/json' },
|
|
24
|
+
body: JSON.stringify({ modulePath, context, data }),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
if (!response.ok) {
|
|
28
|
+
throw new Error(`Failed to render server module: ${response.statusText}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const result = await response.json() as { html: string };
|
|
32
|
+
return result.html;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error('Error rendering server module via SSR server:', error);
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
13
37
|
}
|
|
14
38
|
|
|
15
39
|
/**
|
|
16
|
-
*
|
|
40
|
+
* Adds cache-bust parameter to URL.
|
|
41
|
+
*/
|
|
42
|
+
function addCacheBust(url: string): string {
|
|
43
|
+
const separator = url.includes('?') ? '&' : '?';
|
|
44
|
+
return `${url}${separator}t=${Date.now()}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Loads a module with proper SSR setup for server.js files.
|
|
49
|
+
* For other modules, uses dynamic import with cache-bust.
|
|
50
|
+
* Note: server.js modules are NOT loaded here - they are rendered via renderServerModule
|
|
51
|
+
*/
|
|
52
|
+
export async function loadModule(modulePath: string): Promise<unknown> {
|
|
53
|
+
return import(/* @vite-ignore */ addCacheBust(modulePath));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Fetches tiles from the provided URL using bearer token from parameter
|
|
58
|
+
* @param authToken - Bearer token from request header (e.g., "Bearer xxx")
|
|
59
|
+
* @param tilesUrl - The original tiles URL from the Chrome extension
|
|
17
60
|
* @returns The tiles response object or null if failed
|
|
18
61
|
*/
|
|
19
|
-
export async function fetchTiles(): Promise<any> {
|
|
62
|
+
export async function fetchTiles(authToken?: string, tilesUrl?: string): Promise<any> {
|
|
20
63
|
try {
|
|
21
|
-
|
|
64
|
+
if (!tilesUrl) {
|
|
65
|
+
console.error('No tiles URL provided');
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const headers: Record<string, string> = {};
|
|
70
|
+
|
|
71
|
+
if (authToken) {
|
|
72
|
+
headers['Authorization'] = authToken;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const response = await fetch(tilesUrl, {
|
|
22
76
|
method: 'GET',
|
|
23
|
-
headers
|
|
24
|
-
'Authorization': BEARER_TOKEN
|
|
25
|
-
}
|
|
77
|
+
headers,
|
|
26
78
|
});
|
|
27
79
|
|
|
28
80
|
if (!response.ok) {
|
|
@@ -30,9 +82,7 @@ export async function fetchTiles(): Promise<any> {
|
|
|
30
82
|
return null;
|
|
31
83
|
}
|
|
32
84
|
|
|
33
|
-
|
|
34
|
-
return tilesResponse;
|
|
35
|
-
|
|
85
|
+
return await response.json();
|
|
36
86
|
} catch (error) {
|
|
37
87
|
console.error('Error fetching tiles:', error);
|
|
38
88
|
return null;
|
|
@@ -53,7 +103,7 @@ export function updateTilesSection(
|
|
|
53
103
|
sectionName: string,
|
|
54
104
|
showcaseId: string,
|
|
55
105
|
content: any,
|
|
56
|
-
design: any
|
|
106
|
+
design: any,
|
|
57
107
|
): any {
|
|
58
108
|
const targetPattern = `_${sectionName}_${showcaseId}`;
|
|
59
109
|
|
|
@@ -75,64 +125,156 @@ export function updateTilesSection(
|
|
|
75
125
|
}
|
|
76
126
|
|
|
77
127
|
/**
|
|
78
|
-
* Fetches tiles and returns
|
|
128
|
+
* Fetches tiles and returns all IDs of sections matching the pattern
|
|
79
129
|
* @param sectionName - The section name to match (e.g., 'example-section')
|
|
80
130
|
* @param showcaseId - The showcase ID to match
|
|
81
|
-
* @
|
|
131
|
+
* @param authToken - Bearer token from request header (e.g., "Bearer xxx")
|
|
132
|
+
* @param tilesUrl - The original tiles URL from the Chrome extension
|
|
133
|
+
* @returns Array of section IDs or null if not found
|
|
82
134
|
*/
|
|
83
|
-
export async function
|
|
135
|
+
export async function getSectionIds(sectionName: string, showcaseId: string, authToken?: string, tilesUrl?: string): Promise<string[] | null> {
|
|
84
136
|
try {
|
|
85
|
-
const tilesResponse = await fetchTiles();
|
|
137
|
+
const tilesResponse = await fetchTiles(authToken, tilesUrl);
|
|
86
138
|
if (!tilesResponse || !tilesResponse.tiles) {
|
|
87
139
|
return null;
|
|
88
140
|
}
|
|
89
141
|
|
|
90
142
|
const targetPattern = `_${sectionName}_${showcaseId}`;
|
|
91
143
|
|
|
92
|
-
const
|
|
144
|
+
const targetItems = tilesResponse.tiles.filter((item: any) => {
|
|
93
145
|
const itemId = item.sourceId;
|
|
94
146
|
return itemId?.includes(targetPattern);
|
|
95
147
|
});
|
|
96
148
|
|
|
97
|
-
return
|
|
98
|
-
|
|
149
|
+
return targetItems.length > 0 ? targetItems.map((item: any) => item.id) : null;
|
|
99
150
|
} catch (error) {
|
|
100
|
-
console.error('Error getting section
|
|
151
|
+
console.error('Error getting section IDs:', error);
|
|
101
152
|
return null;
|
|
102
153
|
}
|
|
103
154
|
}
|
|
104
155
|
|
|
156
|
+
/**
|
|
157
|
+
* Gets all showcase IDs for a given section
|
|
158
|
+
* @param sectionName - The section name (e.g., 'example-section')
|
|
159
|
+
* @param distPath - The dist path
|
|
160
|
+
* @returns Array of showcase IDs
|
|
161
|
+
*/
|
|
162
|
+
export function getShowcaseIds(sectionName: string, distPath: string): string[] {
|
|
163
|
+
try {
|
|
164
|
+
const showcasesPath = path.join(distPath, 'sections', sectionName, 'js', 'showcases');
|
|
165
|
+
|
|
166
|
+
if (!fs.existsSync(showcasesPath)) {
|
|
167
|
+
console.error(`Showcases directory not found for section: ${sectionName}`);
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const showcaseIds = fs.readdirSync(showcasesPath)
|
|
172
|
+
.filter((file: string) => file.endsWith('.mjs') && file !== 'translations.mjs')
|
|
173
|
+
.map((file: string) => file.replace('.mjs', ''));
|
|
174
|
+
|
|
175
|
+
return showcaseIds;
|
|
176
|
+
} catch (error) {
|
|
177
|
+
console.error(`Error getting showcase IDs for section ${sectionName}:`, error);
|
|
178
|
+
return [];
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Updates all matching section showcases in custom content
|
|
184
|
+
* @param sectionName - The section name
|
|
185
|
+
* @param showcaseId - The showcase ID
|
|
186
|
+
* @param distPath - The dist path
|
|
187
|
+
* @param customContentSections - The sections array from custom content
|
|
188
|
+
* @param authToken - Bearer token
|
|
189
|
+
* @param tilesUrl - The tiles URL
|
|
190
|
+
* @returns True if at least one section was updated successfully, false otherwise
|
|
191
|
+
*/
|
|
192
|
+
async function updateSectionShowcase(
|
|
193
|
+
sectionName: string,
|
|
194
|
+
showcaseId: string,
|
|
195
|
+
distPath: string,
|
|
196
|
+
customContentSections: Array<Record<string, unknown>>,
|
|
197
|
+
authToken?: string,
|
|
198
|
+
tilesUrl?: string,
|
|
199
|
+
): Promise<boolean> {
|
|
200
|
+
try {
|
|
201
|
+
// Get all section IDs from tiles
|
|
202
|
+
const sectionIds = await getSectionIds(sectionName, showcaseId, authToken, tilesUrl);
|
|
203
|
+
|
|
204
|
+
if (!sectionIds || sectionIds.length === 0) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Process each section ID
|
|
209
|
+
for (const sectionId of sectionIds) {
|
|
210
|
+
// Find the section by ID in custom content
|
|
211
|
+
const targetSection = customContentSections.find((section) => {
|
|
212
|
+
const state = section.state as Record<string, unknown>;
|
|
213
|
+
const data = state.data as Record<string, unknown>;
|
|
214
|
+
return data.tileId === sectionId;
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
if (!targetSection) {
|
|
218
|
+
console.error(`Section not found in custom content with ID: ${sectionId}`);
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Fetch content, design, and html using getShowcaseState
|
|
223
|
+
const state = targetSection.state as Record<string, unknown>;
|
|
224
|
+
// eslint-disable-next-line no-await-in-loop
|
|
225
|
+
const { content, design, html } = await getShowcaseState(
|
|
226
|
+
sectionName,
|
|
227
|
+
showcaseId,
|
|
228
|
+
distPath,
|
|
229
|
+
state.context as Record<string, unknown>,
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
// Update content, design, and html
|
|
233
|
+
const data = state.data as Record<string, unknown>;
|
|
234
|
+
data.content = JSON.stringify(content);
|
|
235
|
+
data.design = JSON.stringify(design);
|
|
236
|
+
targetSection.html = html;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return true;
|
|
240
|
+
} catch (error) {
|
|
241
|
+
console.error(`Error updating ${sectionName} showcase ${showcaseId}:`, error);
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
105
245
|
|
|
106
246
|
/**
|
|
107
|
-
* Fetches custom content and updates
|
|
108
|
-
* @param
|
|
109
|
-
* @param showcaseId - The showcase ID to match
|
|
247
|
+
* Fetches custom content and updates all specified sections with their showcases
|
|
248
|
+
* @param sectionNames - Array of section names to update (e.g., ['example-section', 'test-section'])
|
|
110
249
|
* @param distPath - The dist path for getContentAndDesign
|
|
250
|
+
* @param authToken - Bearer token from request header (e.g., "Bearer xxx")
|
|
251
|
+
* @param customContentUrl - The custom content URL
|
|
252
|
+
* @param tilesUrl - The tiles URL to fetch section IDs
|
|
111
253
|
* @returns The updated custom content response or null if failed
|
|
112
254
|
*/
|
|
113
255
|
export async function updateCustomContent(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
256
|
+
sectionNames: string[],
|
|
257
|
+
distPath: string,
|
|
258
|
+
authToken?: string,
|
|
259
|
+
customContentUrl?: string,
|
|
260
|
+
tilesUrl?: string,
|
|
117
261
|
): Promise<any> {
|
|
118
262
|
try {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (!sectionId) {
|
|
123
|
-
console.error('Section ID not found for:', sectionName, showcaseId);
|
|
263
|
+
if (!customContentUrl || !tilesUrl) {
|
|
264
|
+
console.error('No custom content or tile URL provided');
|
|
124
265
|
return null;
|
|
125
266
|
}
|
|
126
267
|
|
|
127
|
-
// Fetch content and design using getContentAndDesign from preview.ts
|
|
128
|
-
const { content, design } = await getContentAndDesign(sectionName, showcaseId, distPath);
|
|
129
|
-
|
|
130
268
|
// Fetch custom content
|
|
131
|
-
const
|
|
269
|
+
const headers: Record<string, string> = {};
|
|
270
|
+
|
|
271
|
+
if (authToken) {
|
|
272
|
+
headers['Authorization'] = authToken;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const response = await fetch(customContentUrl, {
|
|
132
276
|
method: 'GET',
|
|
133
|
-
headers
|
|
134
|
-
'Authorization': BEARER_TOKEN
|
|
135
|
-
}
|
|
277
|
+
headers,
|
|
136
278
|
});
|
|
137
279
|
|
|
138
280
|
if (!response.ok) {
|
|
@@ -140,29 +282,34 @@ export async function updateCustomContent(
|
|
|
140
282
|
return null;
|
|
141
283
|
}
|
|
142
284
|
|
|
143
|
-
const customContentResponse = await response.json()
|
|
285
|
+
const customContentResponse = await response.json() as Record<string, unknown>;
|
|
144
286
|
|
|
145
|
-
|
|
287
|
+
const customContent = customContentResponse.customContent as Record<string, unknown>;
|
|
288
|
+
if (!customContent || !customContent.sections) {
|
|
146
289
|
console.error('Invalid custom content response structure');
|
|
147
290
|
return null;
|
|
148
291
|
}
|
|
149
292
|
|
|
150
|
-
|
|
151
|
-
const targetSection = customContentResponse.customContent.sections.find((section: any) => {
|
|
152
|
-
return section.state.data.tileId === sectionId;
|
|
153
|
-
});
|
|
293
|
+
const customContentSections = customContent.sections as Array<Record<string, unknown>>;
|
|
154
294
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
295
|
+
// Process all sections and showcases in parallel
|
|
296
|
+
const updatePromises = sectionNames.flatMap((sectionName) => {
|
|
297
|
+
const showcaseIds = getShowcaseIds(sectionName, distPath);
|
|
159
298
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
299
|
+
return showcaseIds.map(showcaseId =>
|
|
300
|
+
updateSectionShowcase(
|
|
301
|
+
sectionName,
|
|
302
|
+
showcaseId,
|
|
303
|
+
distPath,
|
|
304
|
+
customContentSections,
|
|
305
|
+
authToken,
|
|
306
|
+
tilesUrl,
|
|
307
|
+
),
|
|
308
|
+
);
|
|
309
|
+
});
|
|
163
310
|
|
|
311
|
+
await Promise.all(updatePromises);
|
|
164
312
|
return customContentResponse;
|
|
165
|
-
|
|
166
313
|
} catch (error) {
|
|
167
314
|
console.error('Error updating custom content:', error);
|
|
168
315
|
return null;
|