@weaverse/next 1.0.0 → 1.1.0-beta.0

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.
Files changed (47) hide show
  1. package/README.md +7 -1
  2. package/dist/client-boundary.js +1061 -0
  3. package/dist/client-boundary.js.map +1 -0
  4. package/dist/client-boundary.mjs +1017 -0
  5. package/dist/client-boundary.mjs.map +1 -0
  6. package/dist/index.js +307 -1477
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +149 -1100
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/seo-BCFNGChj.js +319 -0
  11. package/dist/seo-BCFNGChj.js.map +1 -0
  12. package/dist/seo-C-S2viuI.mjs +242 -0
  13. package/dist/seo-C-S2viuI.mjs.map +1 -0
  14. package/dist/server.js +626 -1076
  15. package/dist/server.js.map +1 -1
  16. package/dist/server.mjs +620 -803
  17. package/dist/server.mjs.map +1 -1
  18. package/dist/types/client-boundary.d.ts +25 -0
  19. package/dist/types/client-boundary.d.ts.map +1 -0
  20. package/dist/types/index.d.ts +11 -12
  21. package/dist/types/index.d.ts.map +1 -1
  22. package/dist/types/item.d.ts +1 -1
  23. package/dist/types/item.d.ts.map +1 -1
  24. package/dist/types/provider.d.ts +1 -1
  25. package/dist/types/provider.d.ts.map +1 -1
  26. package/dist/types/revalidate-item.d.ts +1 -1
  27. package/dist/types/revalidate-item.d.ts.map +1 -1
  28. package/dist/types/root-provider.d.ts +1 -1
  29. package/dist/types/root-provider.d.ts.map +1 -1
  30. package/dist/types/runtime.d.ts.map +1 -1
  31. package/dist/types/translate.d.ts +56 -0
  32. package/dist/types/translate.d.ts.map +1 -0
  33. package/dist/types/translation-context.d.ts +1 -48
  34. package/dist/types/translation-context.d.ts.map +1 -1
  35. package/dist/types/translation-store.d.ts.map +1 -1
  36. package/dist/types/utils.d.ts +10 -0
  37. package/dist/types/utils.d.ts.map +1 -1
  38. package/package.json +11 -25
  39. package/src/client-boundary.ts +50 -0
  40. package/src/index.ts +42 -52
  41. package/src/provider.tsx +2 -4
  42. package/src/root-provider.tsx +2 -4
  43. package/src/translate.ts +125 -0
  44. package/src/translation-context.tsx +1 -118
  45. package/src/utils.ts +12 -0
  46. package/dist/chunk-LH6AAEIK.mjs +0 -326
  47. package/dist/chunk-LH6AAEIK.mjs.map +0 -1
package/dist/server.js CHANGED
@@ -1,1123 +1,673 @@
1
- 'use strict';
2
-
3
- var schema = require('@weaverse/schema');
4
-
5
- // src/seo.ts
6
- function hasOpenGraphContent(seo) {
7
- return Boolean(seo?.title || seo?.description || seo?.image || seo?.type);
8
- }
9
- function hasTwitterContent(seo) {
10
- return Boolean(seo?.title || seo?.description || seo?.image || seo?.cardType);
11
- }
12
- function normalizeTwitterCard(cardType) {
13
- return cardType === "summary_large_image" ? "summary_large_image" : "summary";
14
- }
15
- function normalizeOpenGraphType(type) {
16
- if (type === "article" || type === "profile" || type === "video.other") {
17
- return type;
18
- }
19
- return "website";
20
- }
21
- function formatWeaverseNextSeoMetadata(seo) {
22
- let index = seo?.robots?.index !== false;
23
- let follow = seo?.robots?.follow !== false;
24
- let metadata = {
25
- robots: { index, follow }
26
- };
27
- if (!seo) {
28
- return metadata;
29
- }
30
- if (seo.title) {
31
- metadata.title = seo.title;
32
- }
33
- if (seo.description) {
34
- metadata.description = seo.description;
35
- }
36
- if (seo.keywords) {
37
- metadata.keywords = seo.keywords;
38
- }
39
- if (seo.canonicalUrl) {
40
- metadata.alternates = { canonical: seo.canonicalUrl };
41
- }
42
- let openGraph = seo.openGraph;
43
- if (hasOpenGraphContent(openGraph)) {
44
- metadata.openGraph = {
45
- title: openGraph?.title,
46
- description: openGraph?.description,
47
- images: openGraph?.image ? [openGraph.image] : void 0,
48
- type: normalizeOpenGraphType(openGraph?.type)
49
- };
50
- }
51
- let twitter = seo.twitter;
52
- if (hasTwitterContent(twitter)) {
53
- metadata.twitter = {
54
- card: normalizeTwitterCard(twitter?.cardType),
55
- title: twitter?.title,
56
- description: twitter?.description,
57
- images: twitter?.image ? [twitter.image] : void 0
58
- };
59
- }
60
- return metadata;
61
- }
62
- function getWeaverseNextSeoMetadata(data) {
63
- if (!data) {
64
- return formatWeaverseNextSeoMetadata(null);
65
- }
66
- let page = "items" in data && "id" in data ? data : data.page ?? null;
67
- return formatWeaverseNextSeoMetadata(page?.seo ?? null);
68
- }
69
-
70
- // src/server/configs.ts
71
- var DEFAULT_WEAVERSE_HOST = "https://studio.weaverse.io";
72
- var DEFAULT_WEAVERSE_API_BASE = "https://api.weaverse.io";
73
- var TRUSTED_STUDIO_DOMAINS = ["weaverse.io", "weaverse.dev"];
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_seo = require("./seo-BCFNGChj.js");
3
+ let _weaverse_schema = require("@weaverse/schema");
4
+ //#region src/server/configs.ts
5
+ const DEFAULT_WEAVERSE_HOST = "https://studio.weaverse.io";
6
+ const DEFAULT_WEAVERSE_API_BASE = "https://api.weaverse.io";
7
+ const TRUSTED_STUDIO_DOMAINS = ["weaverse.io", "weaverse.dev"];
74
8
  function isTrustedStudioHost(host) {
75
- let parsed;
76
- try {
77
- parsed = new URL(host);
78
- } catch {
79
- return false;
80
- }
81
- if (parsed.protocol !== "https:") {
82
- return false;
83
- }
84
- let { hostname } = parsed;
85
- return TRUSTED_STUDIO_DOMAINS.some(
86
- (domain) => hostname === domain || hostname.endsWith(`.${domain}`)
87
- );
9
+ let parsed;
10
+ try {
11
+ parsed = new URL(host);
12
+ } catch {
13
+ return false;
14
+ }
15
+ if (parsed.protocol !== "https:") return false;
16
+ let { hostname } = parsed;
17
+ return TRUSTED_STUDIO_DOMAINS.some((domain) => hostname === domain || hostname.endsWith(`.${domain}`));
88
18
  }
89
19
  function toUrl(value) {
90
- try {
91
- return typeof value === "string" ? new URL(value, "http://localhost") : value;
92
- } catch {
93
- return null;
94
- }
20
+ try {
21
+ return typeof value === "string" ? new URL(value, "http://localhost") : value;
22
+ } catch {
23
+ return null;
24
+ }
95
25
  }
96
26
  function getContextSearchParams(context) {
97
- if (context?.searchParams) {
98
- return new URLSearchParams(context.searchParams);
99
- }
100
- if (context?.url) {
101
- let url = toUrl(context.url);
102
- if (url) {
103
- return new URLSearchParams(url.searchParams);
104
- }
105
- }
106
- return new URLSearchParams();
27
+ if (context?.searchParams) return new URLSearchParams(context.searchParams);
28
+ if (context?.url) {
29
+ let url = toUrl(context.url);
30
+ if (url) return new URLSearchParams(url.searchParams);
31
+ }
32
+ return new URLSearchParams();
107
33
  }
108
34
  function lastParam(searchParams, key) {
109
- let values = searchParams.getAll(key);
110
- return values.length ? values.at(-1) : void 0;
35
+ let values = searchParams.getAll(key);
36
+ return values.length ? values.at(-1) : void 0;
111
37
  }
112
38
  function coerceBool(value) {
113
- return value === "true";
39
+ return value === "true";
114
40
  }
115
41
  function readEnv(env, key) {
116
- let fromConfig = env?.[key];
117
- if (fromConfig !== void 0) {
118
- return fromConfig;
119
- }
120
- if (typeof process !== "undefined" && process.env) {
121
- return process.env[key];
122
- }
123
- return;
42
+ let fromConfig = env?.[key];
43
+ if (fromConfig !== void 0) return fromConfig;
44
+ if (typeof process !== "undefined" && process.env) return process.env[key];
124
45
  }
125
46
  function getWeaverseNextConfigs(context, options = {}) {
126
- let searchParams = getContextSearchParams(context);
127
- let { env } = options;
128
- let queryHost = lastParam(searchParams, "weaverseHost");
129
- let trustedUrlHost = queryHost && isTrustedStudioHost(queryHost) ? new URL(queryHost).origin : "";
130
- let configuredHost = options.weaverseHost || readEnv(env, "WEAVERSE_HOST") || "";
131
- let weaverseHost = trustedUrlHost || configuredHost || DEFAULT_WEAVERSE_HOST;
132
- let weaverseApiBase = trustedUrlHost || options.weaverseApiBase || readEnv(env, "WEAVERSE_PUBLIC_API_BASE") || (configuredHost && configuredHost !== DEFAULT_WEAVERSE_HOST ? configuredHost : DEFAULT_WEAVERSE_API_BASE);
133
- let isRevisionPreview = context?.isRevisionPreview ?? searchParams.has("__revisionId");
134
- let isDesignMode = context?.isDesignMode ?? coerceBool(lastParam(searchParams, "isDesignMode"));
135
- let isPreviewMode = context?.isPreviewMode ?? coerceBool(lastParam(searchParams, "isPreviewMode"));
136
- return {
137
- queryProjectId: lastParam(searchParams, "weaverseProjectId") || "",
138
- envProjectId: readEnv(env, "WEAVERSE_PROJECT_ID") || "",
139
- weaverseHost,
140
- weaverseApiBase,
141
- weaverseVersion: lastParam(searchParams, "weaverseVersion") || options.weaverseVersion || "",
142
- isDesignMode,
143
- isPreviewMode,
144
- isRevisionPreview,
145
- sectionType: context?.sectionType || lastParam(searchParams, "sectionType") || "",
146
- publicEnv: {
147
- PUBLIC_STORE_DOMAIN: readEnv(env, "PUBLIC_STORE_DOMAIN") || "",
148
- PUBLIC_STOREFRONT_API_TOKEN: readEnv(env, "PUBLIC_STOREFRONT_API_TOKEN") || ""
149
- }
150
- };
151
- }
152
-
153
- // src/request-info.ts
154
- function toUrl2(value) {
155
- return typeof value === "string" ? new URL(value, "http://localhost") : value;
156
- }
157
- function getSearchParamsFromContext(context) {
158
- if (context?.searchParams) {
159
- return new URLSearchParams(context.searchParams);
160
- }
161
- if (context?.url) {
162
- let url = toUrl2(context.url);
163
- return new URLSearchParams(url.searchParams);
164
- }
165
- return new URLSearchParams();
166
- }
167
- function withPathPrefix(pathname, i18n) {
168
- let raw = typeof i18n?.pathPrefix === "string" ? i18n.pathPrefix : "";
169
- let segments = raw.split("/").filter(Boolean);
170
- let prefix = segments.length > 0 ? `/${segments.join("/")}` : "";
171
- if (prefix === "" || pathname === prefix || pathname.startsWith(`${prefix}/`)) {
172
- return pathname;
173
- }
174
- return pathname === "/" ? prefix : `${prefix}${pathname}`;
175
- }
176
- function getPathnameFromContext(context) {
177
- if (context?.pathname) {
178
- return withPathPrefix(context.pathname, context.i18n);
179
- }
180
- if (context?.url) {
181
- let url = toUrl2(context.url);
182
- return withPathPrefix(url.pathname || "/", context.i18n);
183
- }
184
- return "/";
185
- }
186
- function coerceQueryValue(value) {
187
- if (value === "true") {
188
- return true;
189
- }
190
- if (value === "false") {
191
- return false;
192
- }
193
- return value;
194
- }
195
- function toQueryRecord(searchParams) {
196
- let queries = {};
197
- for (let [key, value] of searchParams.entries()) {
198
- queries[key] = coerceQueryValue(value);
199
- }
200
- return queries;
201
- }
202
- var TRANSIENT_STUDIO_PARAMS = /* @__PURE__ */ new Set([
203
- "weaverseDraftItem",
204
- // Legacy name from the original design-mode draft-item spike. Keep it out of
205
- // runtime requestInfo too, in case an older Builder bundle is in front of a
206
- // newer Next storefront.
207
- "__weaverseDraftItem"
208
- ]);
209
- function getRequestInfoSearchParams(context) {
210
- let searchParams = new URLSearchParams(getSearchParamsFromContext(context));
211
- for (let key of TRANSIENT_STUDIO_PARAMS) {
212
- searchParams.delete(key);
213
- }
214
- return searchParams;
215
- }
216
- function buildWeaverseNextRequestInfo(context) {
217
- let searchParams = getRequestInfoSearchParams(context);
218
- let search = searchParams.toString();
219
- return {
220
- pathname: getPathnameFromContext(context),
221
- search: search ? `?${search}` : "",
222
- queries: toQueryRecord(searchParams),
223
- ...context?.i18n ? { i18n: context.i18n } : {},
224
- ...context?.pageType ? { pageType: context.pageType } : {},
225
- ...context?.handle ? { handle: context.handle } : {}
226
- };
227
- }
228
-
229
- // src/server/normalize-page-url.ts
230
- var KEPT_PARAM_RE = /^(?:__revisionId|__weaverseDraftItem|isDesignMode|weaverse)/;
231
- var DATA_SUFFIX = ".data";
47
+ let searchParams = getContextSearchParams(context);
48
+ let { env } = options;
49
+ let queryHost = lastParam(searchParams, "weaverseHost");
50
+ let trustedUrlHost = queryHost && isTrustedStudioHost(queryHost) ? new URL(queryHost).origin : "";
51
+ let configuredHost = options.weaverseHost || readEnv(env, "WEAVERSE_HOST") || "";
52
+ let weaverseHost = trustedUrlHost || configuredHost || DEFAULT_WEAVERSE_HOST;
53
+ let weaverseApiBase = trustedUrlHost || options.weaverseApiBase || readEnv(env, "WEAVERSE_PUBLIC_API_BASE") || (configuredHost && configuredHost !== DEFAULT_WEAVERSE_HOST ? configuredHost : DEFAULT_WEAVERSE_API_BASE);
54
+ let isRevisionPreview = context?.isRevisionPreview ?? searchParams.has("__revisionId");
55
+ let isDesignMode = context?.isDesignMode ?? coerceBool(lastParam(searchParams, "isDesignMode"));
56
+ let isPreviewMode = context?.isPreviewMode ?? coerceBool(lastParam(searchParams, "isPreviewMode"));
57
+ return {
58
+ queryProjectId: lastParam(searchParams, "weaverseProjectId") || "",
59
+ envProjectId: readEnv(env, "WEAVERSE_PROJECT_ID") || "",
60
+ weaverseHost,
61
+ weaverseApiBase,
62
+ weaverseVersion: lastParam(searchParams, "weaverseVersion") || options.weaverseVersion || "",
63
+ isDesignMode,
64
+ isPreviewMode,
65
+ isRevisionPreview,
66
+ sectionType: context?.sectionType || lastParam(searchParams, "sectionType") || "",
67
+ publicEnv: {
68
+ PUBLIC_STORE_DOMAIN: readEnv(env, "PUBLIC_STORE_DOMAIN") || "",
69
+ PUBLIC_STOREFRONT_API_TOKEN: readEnv(env, "PUBLIC_STOREFRONT_API_TOKEN") || ""
70
+ }
71
+ };
72
+ }
73
+ //#endregion
74
+ //#region src/server/normalize-page-url.ts
75
+ const KEPT_PARAM_RE = /^(?:__revisionId|__weaverseDraftItem|isDesignMode|weaverse)/;
76
+ const DATA_SUFFIX = ".data";
232
77
  function normalizeNextPageUrl(url) {
233
- let parsed;
234
- try {
235
- parsed = new URL(url);
236
- } catch {
237
- try {
238
- parsed = new URL(url, "http://localhost");
239
- } catch {
240
- return url;
241
- }
242
- }
243
- let kept = [...parsed.searchParams].filter(([key]) => KEPT_PARAM_RE.test(key));
244
- kept.sort(([a], [b]) => a.localeCompare(b));
245
- let search = new URLSearchParams(kept).toString();
246
- let { pathname } = parsed;
247
- if (pathname.endsWith(DATA_SUFFIX)) {
248
- pathname = pathname.slice(0, -DATA_SUFFIX.length);
249
- }
250
- return `${parsed.origin}${pathname}${search ? `?${search}` : ""}`;
78
+ let parsed;
79
+ try {
80
+ parsed = new URL(url);
81
+ } catch {
82
+ try {
83
+ parsed = new URL(url, "http://localhost");
84
+ } catch {
85
+ return url;
86
+ }
87
+ }
88
+ let kept = [...parsed.searchParams].filter(([key]) => KEPT_PARAM_RE.test(key));
89
+ kept.sort(([a], [b]) => a.localeCompare(b));
90
+ let search = new URLSearchParams(kept).toString();
91
+ let { pathname } = parsed;
92
+ if (pathname.endsWith(DATA_SUFFIX)) pathname = pathname.slice(0, -5);
93
+ return `${parsed.origin}${pathname}${search ? `?${search}` : ""}`;
251
94
  }
252
95
  function resolveRequestUrl(context) {
253
- if (context?.url) {
254
- let raw = String(context.url);
255
- let url = new URL(raw, "http://localhost");
256
- let pathname2 = withPathPrefix(url.pathname, context.i18n);
257
- if (pathname2 === url.pathname) {
258
- return raw;
259
- }
260
- url.pathname = pathname2;
261
- return url.toString();
262
- }
263
- let pathname = withPathPrefix(context?.pathname || "/", context?.i18n);
264
- let search = context?.searchParams ? new URLSearchParams(context.searchParams).toString() : "";
265
- return `http://localhost${pathname}${search ? `?${search}` : ""}`;
266
- }
267
- var DENIED_ROUTE_CONTEXT_PARAMS = [
268
- "weaverseprojectid",
269
- "weaversehost",
270
- "weaverseapikey",
271
- "weaverseapibase",
272
- "weaversepublicapibase",
273
- "weaverseversion",
274
- "projectid",
275
- "weaversedraftitem",
276
- "__weaversedraftitem",
277
- "_rsc"
278
- ];
279
- var ROUTE_CONTEXT_I18N_KEYS = [
280
- "country",
281
- "label",
282
- "language",
283
- "locale",
284
- "pathPrefix"
285
- ];
286
- function sanitizeRouteContextSearch(search) {
287
- let params = new URLSearchParams(search);
288
- let denied = new Set(DENIED_ROUTE_CONTEXT_PARAMS);
289
- for (let key of [...new Set(params.keys())]) {
290
- if (denied.has(key.toLowerCase())) {
291
- params.delete(key);
292
- }
293
- }
294
- let serialized = params.toString();
295
- return serialized ? `?${serialized}` : "";
296
- }
297
-
298
- // src/utils.ts
299
- function generateDataFromSchema(schema) {
300
- let data = {};
301
- if (!schema) {
302
- return data;
303
- }
304
- let groups = schema.settings ?? schema.inspector ?? [];
305
- for (let group of groups) {
306
- for (let input of group?.inputs ?? []) {
307
- let { name, defaultValue } = input;
308
- if (name && defaultValue !== null && defaultValue !== void 0) {
309
- data[name] = defaultValue;
310
- }
311
- }
312
- }
313
- return data;
314
- }
315
-
316
- // src/server/revalidate-handler.ts
317
- var NO_STORE_HEADERS = {
318
- "Content-Type": "application/json",
319
- "Cache-Control": "no-store"
96
+ if (context?.url) {
97
+ let raw = String(context.url);
98
+ let url = new URL(raw, "http://localhost");
99
+ let pathname = require_seo.withPathPrefix(url.pathname, context.i18n);
100
+ if (pathname === url.pathname) return raw;
101
+ url.pathname = pathname;
102
+ return url.toString();
103
+ }
104
+ let pathname = require_seo.withPathPrefix(context?.pathname || "/", context?.i18n);
105
+ let search = context?.searchParams ? new URLSearchParams(context.searchParams).toString() : "";
106
+ return `http://localhost${pathname}${search ? `?${search}` : ""}`;
107
+ }
108
+ //#endregion
109
+ //#region src/server/revalidate-handler.ts
110
+ const NO_STORE_HEADERS = {
111
+ "Content-Type": "application/json",
112
+ "Cache-Control": "no-store"
320
113
  };
321
- var STATUS_OK = 200;
322
- var STATUS_BAD_REQUEST = 400;
323
- var STATUS_NOT_FOUND = 404;
324
- var STATUS_UNPROCESSABLE = 422;
325
- var STATUS_SERVER_ERROR = 500;
326
- var MAX_PATHNAME_LENGTH = 2048;
327
- var MAX_SEARCH_LENGTH = 8192;
328
- var MAX_HANDLE_LENGTH = 512;
329
- var MAX_I18N_FIELD_LENGTH = 256;
330
- var CONTROL_CHAR_PATTERN = /[\u0000-\u001F\u007F]/;
114
+ const STATUS_OK = 200;
115
+ const STATUS_BAD_REQUEST = 400;
116
+ const STATUS_NOT_FOUND = 404;
117
+ const STATUS_UNPROCESSABLE = 422;
118
+ const STATUS_SERVER_ERROR = 500;
119
+ const MAX_PATHNAME_LENGTH = 2048;
120
+ const MAX_SEARCH_LENGTH = 8192;
121
+ const MAX_HANDLE_LENGTH = 512;
122
+ const MAX_I18N_FIELD_LENGTH = 256;
123
+ const CONTROL_CHAR_PATTERN = /[\u0000-\u001F\u007F]/;
331
124
  function isValidPathname(pathname) {
332
- if (!pathname || pathname.length > MAX_PATHNAME_LENGTH) {
333
- return false;
334
- }
335
- if (pathname[0] !== "/" || pathname.startsWith("//")) {
336
- return false;
337
- }
338
- if (pathname.includes("\\") || pathname.includes("?")) {
339
- return false;
340
- }
341
- if (pathname.includes("#") || CONTROL_CHAR_PATTERN.test(pathname)) {
342
- return false;
343
- }
344
- return true;
125
+ if (!pathname || pathname.length > MAX_PATHNAME_LENGTH) return false;
126
+ if (pathname[0] !== "/" || pathname.startsWith("//")) return false;
127
+ if (pathname.includes("\\") || pathname.includes("?")) return false;
128
+ if (pathname.includes("#") || CONTROL_CHAR_PATTERN.test(pathname)) return false;
129
+ return true;
345
130
  }
346
131
  function isPlainObject(value) {
347
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
348
- return false;
349
- }
350
- let proto = Object.getPrototypeOf(value);
351
- return proto === Object.prototype || proto === null;
132
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
133
+ let proto = Object.getPrototypeOf(value);
134
+ return proto === Object.prototype || proto === null;
352
135
  }
353
136
  function sanitizeRouteContextI18n(input) {
354
- if (input === void 0) {
355
- return;
356
- }
357
- if (!isPlainObject(input)) {
358
- return null;
359
- }
360
- let source = input;
361
- let allowed = new Set(ROUTE_CONTEXT_I18N_KEYS);
362
- for (let key of Object.keys(source)) {
363
- if (!allowed.has(key)) {
364
- return null;
365
- }
366
- }
367
- let result = {};
368
- for (let key of ROUTE_CONTEXT_I18N_KEYS) {
369
- let value = source[key];
370
- if (value === void 0) {
371
- continue;
372
- }
373
- if (typeof value !== "string" || value.length > MAX_I18N_FIELD_LENGTH) {
374
- return null;
375
- }
376
- result[key] = value;
377
- }
378
- return Object.keys(result).length ? result : void 0;
137
+ if (input === void 0) return;
138
+ if (!isPlainObject(input)) return null;
139
+ let source = input;
140
+ let allowed = new Set(require_seo.ROUTE_CONTEXT_I18N_KEYS);
141
+ for (let key of Object.keys(source)) if (!allowed.has(key)) return null;
142
+ let result = {};
143
+ for (let key of require_seo.ROUTE_CONTEXT_I18N_KEYS) {
144
+ let value = source[key];
145
+ if (value === void 0) continue;
146
+ if (typeof value !== "string" || value.length > MAX_I18N_FIELD_LENGTH) return null;
147
+ result[key] = value;
148
+ }
149
+ return Object.keys(result).length ? result : void 0;
379
150
  }
380
151
  function reconstructRouteContext(request, routeContext) {
381
- if (typeof routeContext !== "object" || routeContext === null || Array.isArray(routeContext)) {
382
- return null;
383
- }
384
- let { pathname, search, handle, pageType, i18n } = routeContext;
385
- if (typeof pathname !== "string" || !isValidPathname(pathname)) {
386
- return null;
387
- }
388
- if (typeof search !== "string" || search.length > MAX_SEARCH_LENGTH) {
389
- return null;
390
- }
391
- let rawSearch = search;
392
- if (rawSearch.length && !rawSearch.startsWith("?")) {
393
- return null;
394
- }
395
- let sanitizedI18n = sanitizeRouteContextI18n(i18n);
396
- if (sanitizedI18n === null) {
397
- return null;
398
- }
399
- let resolvedPageType;
400
- if (pageType !== void 0) {
401
- let parsed = schema.PageTypeSchema.safeParse(pageType);
402
- if (!parsed.success) {
403
- return null;
404
- }
405
- resolvedPageType = parsed.data;
406
- }
407
- let resolvedHandle;
408
- if (handle !== void 0) {
409
- if (typeof handle !== "string" || !handle || handle.length > MAX_HANDLE_LENGTH) {
410
- return null;
411
- }
412
- resolvedHandle = handle;
413
- }
414
- let endpointUrl = new URL(request.url);
415
- let routeUrl = new URL(endpointUrl.origin);
416
- routeUrl.pathname = pathname;
417
- routeUrl.search = sanitizeRouteContextSearch(rawSearch);
418
- let canonicalPathname = routeUrl.pathname;
419
- let searchParams = routeUrl.searchParams;
420
- let lastParam2 = (key) => {
421
- let values = searchParams.getAll(key);
422
- return values.length ? values.at(-1) : void 0;
423
- };
424
- return {
425
- pathname: canonicalPathname,
426
- searchParams,
427
- url: routeUrl,
428
- // Headers come from the actual same-origin POST, never its JSON body.
429
- headers: new Headers(request.headers),
430
- ...sanitizedI18n ? { i18n: sanitizedI18n } : {},
431
- ...resolvedPageType ? { pageType: resolvedPageType } : {},
432
- ...resolvedHandle ? { handle: resolvedHandle } : {},
433
- isDesignMode: lastParam2("isDesignMode") === "true",
434
- isPreviewMode: lastParam2("isPreviewMode") === "true",
435
- isRevisionPreview: searchParams.has("__revisionId"),
436
- sectionType: lastParam2("sectionType") || void 0
437
- };
152
+ if (typeof routeContext !== "object" || routeContext === null || Array.isArray(routeContext)) return null;
153
+ let { pathname, search, handle, pageType, i18n } = routeContext;
154
+ if (typeof pathname !== "string" || !isValidPathname(pathname)) return null;
155
+ if (typeof search !== "string" || search.length > MAX_SEARCH_LENGTH) return null;
156
+ let rawSearch = search;
157
+ if (rawSearch.length && !rawSearch.startsWith("?")) return null;
158
+ let sanitizedI18n = sanitizeRouteContextI18n(i18n);
159
+ if (sanitizedI18n === null) return null;
160
+ let resolvedPageType;
161
+ if (pageType !== void 0) {
162
+ let parsed = _weaverse_schema.PageTypeSchema.safeParse(pageType);
163
+ if (!parsed.success) return null;
164
+ resolvedPageType = parsed.data;
165
+ }
166
+ let resolvedHandle;
167
+ if (handle !== void 0) {
168
+ if (typeof handle !== "string" || !handle || handle.length > MAX_HANDLE_LENGTH) return null;
169
+ resolvedHandle = handle;
170
+ }
171
+ let endpointUrl = new URL(request.url);
172
+ let routeUrl = new URL(endpointUrl.origin);
173
+ routeUrl.pathname = pathname;
174
+ routeUrl.search = require_seo.sanitizeRouteContextSearch(rawSearch);
175
+ let canonicalPathname = routeUrl.pathname;
176
+ let searchParams = routeUrl.searchParams;
177
+ let lastParam = (key) => {
178
+ let values = searchParams.getAll(key);
179
+ return values.length ? values.at(-1) : void 0;
180
+ };
181
+ return {
182
+ pathname: canonicalPathname,
183
+ searchParams,
184
+ url: routeUrl,
185
+ headers: new Headers(request.headers),
186
+ ...sanitizedI18n ? { i18n: sanitizedI18n } : {},
187
+ ...resolvedPageType ? { pageType: resolvedPageType } : {},
188
+ ...resolvedHandle ? { handle: resolvedHandle } : {},
189
+ isDesignMode: lastParam("isDesignMode") === "true",
190
+ isPreviewMode: lastParam("isPreviewMode") === "true",
191
+ isRevisionPreview: searchParams.has("__revisionId"),
192
+ sectionType: lastParam("sectionType") || void 0
193
+ };
438
194
  }
439
195
  function json(body, status) {
440
- return new Response(JSON.stringify(body), {
441
- status,
442
- headers: NO_STORE_HEADERS
443
- });
196
+ return new Response(JSON.stringify(body), {
197
+ status,
198
+ headers: NO_STORE_HEADERS
199
+ });
444
200
  }
445
201
  function parseDraftItem(payload) {
446
- if (typeof payload !== "object" || payload === null) {
447
- return null;
448
- }
449
- let draftItem = payload.draftItem;
450
- if (typeof draftItem !== "object" || draftItem === null) {
451
- return null;
452
- }
453
- let { id, type } = draftItem;
454
- if (typeof id !== "string" || !id || typeof type !== "string" || !type) {
455
- return null;
456
- }
457
- return draftItem;
202
+ if (typeof payload !== "object" || payload === null) return null;
203
+ let draftItem = payload.draftItem;
204
+ if (typeof draftItem !== "object" || draftItem === null) return null;
205
+ let { id, type } = draftItem;
206
+ if (typeof id !== "string" || !id || typeof type !== "string" || !type) return null;
207
+ return draftItem;
458
208
  }
459
209
  function createWeaverseNextRevalidateHandler(config) {
460
- return {
461
- POST: async (request) => {
462
- let payload;
463
- try {
464
- payload = await request.json();
465
- } catch {
466
- return json({ error: "invalid-payload" }, STATUS_BAD_REQUEST);
467
- }
468
- let draftItem = parseDraftItem(payload);
469
- if (!draftItem) {
470
- return json({ error: "invalid-payload" }, STATUS_BAD_REQUEST);
471
- }
472
- let requestContext;
473
- let body = payload;
474
- if (Object.hasOwn(body, "routeContext")) {
475
- let reconstructed = reconstructRouteContext(request, body.routeContext);
476
- if (!reconstructed) {
477
- return json({ error: "invalid-route-context" }, STATUS_BAD_REQUEST);
478
- }
479
- requestContext = reconstructed;
480
- }
481
- let client;
482
- try {
483
- client = await config.getClient(request, requestContext);
484
- } catch (error) {
485
- console.error("\u274C Revalidate handler getClient failed.", error);
486
- return json({ error: "client-init-failed" }, STATUS_SERVER_ERROR);
487
- }
488
- let component = client.components.find(
489
- (candidate) => candidate?.schema?.type === draftItem.type
490
- );
491
- if (!component) {
492
- return json({ error: "unknown-component-type" }, STATUS_NOT_FOUND);
493
- }
494
- if (typeof component.loader !== "function") {
495
- return json({ error: "missing-loader" }, STATUS_UNPROCESSABLE);
496
- }
497
- try {
498
- let loaderData = await component.loader({
499
- data: {
500
- ...generateDataFromSchema(component.schema),
501
- ...draftItem.data
502
- },
503
- weaverse: client,
504
- context: client.requestContext,
505
- commerce: client.commerce
506
- });
507
- return json({ loaderData: loaderData ?? null }, STATUS_OK);
508
- } catch (error) {
509
- console.error(
510
- "\u274C Item loader revalidation failed.",
511
- draftItem.type,
512
- draftItem.id,
513
- error
514
- );
515
- return json({ error: "loader-failed" }, STATUS_SERVER_ERROR);
516
- }
517
- }
518
- };
519
- }
520
-
521
- // src/loader.ts
522
- function isItemNode(node) {
523
- return typeof node === "object" && node !== null && typeof node.type === "string";
524
- }
525
- function cloneItem(item) {
526
- return {
527
- ...item,
528
- children: Array.isArray(item.children) ? item.children.map(
529
- (child) => isItemNode(child) ? cloneItem(child) : { ...child }
530
- ) : item.children
531
- };
532
- }
533
- async function runWeaverseComponentLoaders(args) {
534
- let { client, context, commerce } = args;
535
- let sourceData = args.data ?? client.data;
536
- if (!sourceData) {
537
- return null;
538
- }
539
- if (!sourceData.page.items.length) {
540
- return sourceData;
541
- }
542
- let data = {
543
- ...sourceData,
544
- page: {
545
- ...sourceData.page,
546
- items: sourceData.page.items.map(cloneItem)
547
- }
548
- };
549
- let items = data.page.items;
550
- let componentMap = /* @__PURE__ */ new Map();
551
- for (let component of client.components) {
552
- if (component?.schema?.type) {
553
- componentMap.set(component.schema.type, component);
554
- }
555
- }
556
- let visited = /* @__PURE__ */ new Set();
557
- let resolvedContext = context ?? client.requestContext;
558
- let resolvedCommerce = commerce ?? client.commerce;
559
- let resolvedWeaverse = resolvedCommerce === client.commerce ? client : {
560
- ...client,
561
- commerce: resolvedCommerce,
562
- storefront: resolvedCommerce?.storefront
563
- };
564
- async function walk(nodes) {
565
- for (let item of nodes) {
566
- if (!item || visited.has(item.id)) {
567
- continue;
568
- }
569
- visited.add(item.id);
570
- let component = componentMap.get(item.type);
571
- if (component?.loader) {
572
- try {
573
- item.loaderData = await component.loader({
574
- data: { ...generateDataFromSchema(component.schema), ...item.data },
575
- weaverse: resolvedWeaverse,
576
- context: resolvedContext,
577
- commerce: resolvedCommerce
578
- });
579
- } catch (error) {
580
- console.warn("\u274C Item loader run failed.", item.type, item.id, error);
581
- }
582
- }
583
- let children = item.children;
584
- if (Array.isArray(children)) {
585
- let inlineChildren = children.filter(
586
- isItemNode
587
- );
588
- if (inlineChildren.length) {
589
- await walk(inlineChildren);
590
- }
591
- }
592
- }
593
- }
594
- await walk(items);
595
- return data;
596
- }
597
-
598
- // src/server/server-client.ts
599
- var DEFAULT_FETCH_TIMEOUT_MS = 1e4;
600
- var RANDOM_ID_RADIX = 36;
601
- var RANDOM_ID_SLICE_START = 2;
602
- var MAX_CUSTOM_PAGE_PAGES = 100;
603
- var JSON_HEADERS = {
604
- "Content-Type": "application/json",
605
- Accept: "application/json",
606
- "Accept-Encoding": "gzip, deflate, br"
210
+ return { POST: async (request) => {
211
+ let payload;
212
+ try {
213
+ payload = await request.json();
214
+ } catch {
215
+ return json({ error: "invalid-payload" }, STATUS_BAD_REQUEST);
216
+ }
217
+ let draftItem = parseDraftItem(payload);
218
+ if (!draftItem) return json({ error: "invalid-payload" }, STATUS_BAD_REQUEST);
219
+ let requestContext;
220
+ let body = payload;
221
+ if (Object.hasOwn(body, "routeContext")) {
222
+ let reconstructed = reconstructRouteContext(request, body.routeContext);
223
+ if (!reconstructed) return json({ error: "invalid-route-context" }, STATUS_BAD_REQUEST);
224
+ requestContext = reconstructed;
225
+ }
226
+ let client;
227
+ try {
228
+ client = await config.getClient(request, requestContext);
229
+ } catch (error) {
230
+ console.error("❌ Revalidate handler getClient failed.", error);
231
+ return json({ error: "client-init-failed" }, STATUS_SERVER_ERROR);
232
+ }
233
+ let component = client.components.find((candidate) => candidate?.schema?.type === draftItem.type);
234
+ if (!component) return json({ error: "unknown-component-type" }, STATUS_NOT_FOUND);
235
+ if (typeof component.loader !== "function") return json({ error: "missing-loader" }, STATUS_UNPROCESSABLE);
236
+ try {
237
+ return json({ loaderData: await component.loader({
238
+ data: {
239
+ ...require_seo.generateDataFromSchema(component.schema),
240
+ ...draftItem.data
241
+ },
242
+ weaverse: client,
243
+ context: client.requestContext,
244
+ commerce: client.commerce
245
+ }) ?? null }, STATUS_OK);
246
+ } catch (error) {
247
+ console.error("❌ Item loader revalidation failed.", draftItem.type, draftItem.id, error);
248
+ return json({ error: "loader-failed" }, STATUS_SERVER_ERROR);
249
+ }
250
+ } };
251
+ }
252
+ //#endregion
253
+ //#region src/server/server-client.ts
254
+ const DEFAULT_FETCH_TIMEOUT_MS = 1e4;
255
+ const RANDOM_ID_RADIX = 36;
256
+ const RANDOM_ID_SLICE_START = 2;
257
+ const MAX_CUSTOM_PAGE_PAGES = 100;
258
+ const JSON_HEADERS = {
259
+ "Content-Type": "application/json",
260
+ Accept: "application/json",
261
+ "Accept-Encoding": "gzip, deflate, br"
607
262
  };
608
263
  function asThemeSchema(schema) {
609
- return schema && typeof schema === "object" ? schema : void 0;
264
+ return schema && typeof schema === "object" ? schema : void 0;
610
265
  }
611
266
  function generateUuid() {
612
- if (typeof crypto !== "undefined" && "randomUUID" in crypto) {
613
- return crypto.randomUUID();
614
- }
615
- return `id-${Math.random().toString(RANDOM_ID_RADIX).slice(RANDOM_ID_SLICE_START)}`;
267
+ if (typeof crypto !== "undefined" && "randomUUID" in crypto) return crypto.randomUUID();
268
+ return `id-${Math.random().toString(RANDOM_ID_RADIX).slice(RANDOM_ID_SLICE_START)}`;
616
269
  }
617
270
  function normalizeWeaverseNextPageAssignment(input) {
618
- if (!input || typeof input !== "object") {
619
- return;
620
- }
621
- let { projectId, type, handle, locale, meta } = input;
622
- if (typeof projectId !== "string" || typeof type !== "string" || typeof handle !== "string") {
623
- return;
624
- }
625
- let normalized = {
626
- projectId,
627
- type,
628
- handle,
629
- locale: typeof locale === "string" ? locale : ""
630
- };
631
- if (meta && typeof meta === "object") {
632
- normalized.meta = meta;
633
- }
634
- return normalized;
271
+ if (!input || typeof input !== "object") return;
272
+ let { projectId, type, handle, locale, meta } = input;
273
+ if (typeof projectId !== "string" || typeof type !== "string" || typeof handle !== "string") return;
274
+ let normalized = {
275
+ projectId,
276
+ type,
277
+ handle,
278
+ locale: typeof locale === "string" ? locale : ""
279
+ };
280
+ if (meta && typeof meta === "object") normalized.meta = meta;
281
+ return normalized;
635
282
  }
636
283
  var NextServerClient = class {
637
- components;
638
- commerce;
639
- requestContext;
640
- themeSchema;
641
- themeSettings;
642
- data = null;
643
- dataContext = {};
644
- configs;
645
- _projectIdInput;
646
- _baseConfigs;
647
- _fetch;
648
- _cache;
649
- _fetchTimeoutMs;
650
- _resolvedProjectId;
651
- constructor(config) {
652
- this.components = config.components;
653
- this.commerce = config.commerce;
654
- this.requestContext = config.requestContext;
655
- this.themeSchema = config.themeSchema;
656
- this.themeSettings = {
657
- ...generateDataFromSchema(config.themeSchema),
658
- ...config.themeSettings
659
- };
660
- this._projectIdInput = config.projectId;
661
- this._fetch = config.fetch ?? globalThis.fetch;
662
- this._cache = config.cache;
663
- this._fetchTimeoutMs = config.fetchTimeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS;
664
- this._baseConfigs = getWeaverseNextConfigs(config.requestContext, {
665
- env: config.env,
666
- weaverseHost: config.weaverseHost,
667
- weaverseApiBase: config.weaverseApiBase,
668
- weaverseVersion: config.weaverseVersion
669
- });
670
- this.configs = this._buildPublicConfigs(
671
- this._baseConfigs.queryProjectId || (typeof this._projectIdInput === "string" ? this._projectIdInput.trim() : "") || this._baseConfigs.envProjectId
672
- );
673
- }
674
- get projectId() {
675
- return this.configs.projectId;
676
- }
677
- /** Compatibility alias so loaders can call `weaverse.storefront.query(...)`. */
678
- get storefront() {
679
- return this.commerce?.storefront;
680
- }
681
- _buildPublicConfigs(projectId) {
682
- let base = this._baseConfigs;
683
- return {
684
- projectId,
685
- weaverseHost: base.weaverseHost,
686
- weaverseApiBase: base.weaverseApiBase,
687
- weaversePublicApiBase: base.weaverseApiBase,
688
- weaverseVersion: base.weaverseVersion,
689
- isDesignMode: base.isDesignMode,
690
- isPreviewMode: base.isPreviewMode,
691
- isRevisionPreview: base.isRevisionPreview,
692
- sectionType: base.sectionType,
693
- publicEnv: base.publicEnv
694
- };
695
- }
696
- resolveProjectId = async () => {
697
- if (this._resolvedProjectId !== void 0) {
698
- return this._resolvedProjectId;
699
- }
700
- let resolved = this._baseConfigs.queryProjectId;
701
- if (!resolved && typeof this._projectIdInput === "function") {
702
- try {
703
- let value = await this._projectIdInput(this.requestContext);
704
- if (typeof value === "string" && value.trim()) {
705
- resolved = value.trim();
706
- }
707
- } catch (error) {
708
- console.warn(
709
- "[WeaverseNextServerClient] projectId resolver threw, falling back.",
710
- error
711
- );
712
- }
713
- }
714
- if (!resolved && typeof this._projectIdInput === "string") {
715
- resolved = this._projectIdInput.trim();
716
- }
717
- if (!resolved) {
718
- resolved = this._baseConfigs.envProjectId;
719
- }
720
- this._resolvedProjectId = resolved;
721
- this.configs = this._buildPublicConfigs(resolved);
722
- return resolved;
723
- };
724
- fetchWithCache = async (url, options = {}) => {
725
- let { revalidate, tags, ...init } = options;
726
- let requestInit = { ...init };
727
- let { isDesignMode, isRevisionPreview } = this._baseConfigs;
728
- if (isDesignMode || isRevisionPreview) {
729
- requestInit.cache = "no-store";
730
- } else if (requestInit.cache === void 0) {
731
- let effectiveRevalidate = revalidate ?? this._cache?.revalidate;
732
- let effectiveTags = tags ?? this._cache?.tags;
733
- if (effectiveRevalidate !== void 0 || effectiveTags?.length) {
734
- requestInit.next = {
735
- ...effectiveRevalidate === void 0 ? {} : { revalidate: effectiveRevalidate },
736
- ...effectiveTags?.length ? { tags: effectiveTags } : {}
737
- };
738
- }
739
- }
740
- let controller = new AbortController();
741
- let timeoutId = setTimeout(() => controller.abort(), this._fetchTimeoutMs);
742
- try {
743
- let response = await this._fetch(url, {
744
- ...requestInit,
745
- signal: requestInit.signal ?? controller.signal
746
- });
747
- if (!response.ok) {
748
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
749
- }
750
- return await response.json();
751
- } finally {
752
- clearTimeout(timeoutId);
753
- }
754
- };
755
- _buildCustomPagesUrl(projectId, options, cursor) {
756
- let params = new URLSearchParams();
757
- if (options.locale) {
758
- params.set("locale", options.locale);
759
- }
760
- if (options.limit) {
761
- params.set("limit", String(options.limit));
762
- }
763
- if (cursor) {
764
- params.set("cursor", cursor);
765
- }
766
- let qs = params.toString();
767
- return `${this._baseConfigs.weaverseApiBase}/api/public/v1/projects/${projectId}/custom-pages${qs ? `?${qs}` : ""}`;
768
- }
769
- /**
770
- * Fetch all published custom pages for sitemap generation. Mirrors Hydrogen's
771
- * helper but uses Next's fetch cache knobs (`revalidate` / `tags`). It returns
772
- * accumulated results on partial pagination failure so a single API hiccup
773
- * does not break sitemap generation entirely.
774
- */
775
- fetchCustomPages = async (options = {}) => {
776
- let projectId = await this.resolveProjectId();
777
- let entries = [];
778
- if (!projectId) {
779
- console.warn(
780
- "[WeaverseNext] Failed to fetch custom pages: missing projectId"
781
- );
782
- return entries;
783
- }
784
- let cursor = null;
785
- for (let page = 0; page < MAX_CUSTOM_PAGE_PAGES; page += 1) {
786
- let url = this._buildCustomPagesUrl(projectId, options, cursor);
787
- try {
788
- let result = await this.fetchWithCache(url, {
789
- revalidate: options.revalidate,
790
- tags: options.tags
791
- });
792
- entries.push(...result.data ?? []);
793
- if (!result.nextCursor) {
794
- return entries;
795
- }
796
- cursor = result.nextCursor;
797
- } catch (error) {
798
- let message = error instanceof Error ? error.message : String(error);
799
- console.warn(
800
- entries.length === 0 ? `[WeaverseNext] Failed to fetch custom pages: ${message}` : `[WeaverseNext] Custom pages pagination interrupted: ${message}`
801
- );
802
- return entries;
803
- }
804
- }
805
- console.warn("[WeaverseNext] Custom pages pagination cap reached");
806
- return entries;
807
- };
808
- _generateFallbackPage(message) {
809
- let rootId = generateUuid();
810
- return {
811
- id: `fallback_page_${rootId}`,
812
- rootId,
813
- name: "Default Page",
814
- items: [
815
- {
816
- type: "main",
817
- id: rootId,
818
- data: { dangerouslySetInnerHTML: { __html: message } }
819
- }
820
- ]
821
- };
822
- }
823
- /**
824
- * Recursively materialize a section preset (and its preset children) into a
825
- * flat list of page items, returning the new item id. Ported from Hydrogen's
826
- * `recursivelyAddDataItem`. Returns `undefined` when the type isn't registered.
827
- */
828
- _buildPreviewItems(type, items, initData = {}) {
829
- let component = this.components.find((c) => c.schema?.type === type);
830
- if (!component) {
831
- return;
832
- }
833
- let { children, ...data } = component.schema?.presets ?? {};
834
- let childIds = [];
835
- if (children) {
836
- for (let child of children) {
837
- let { type: childType, children: _children, ...childData } = child;
838
- let childId = this._buildPreviewItems(childType, items, childData);
839
- if (childId) {
840
- childIds.push({ id: childId });
841
- }
842
- }
843
- }
844
- let id = generateUuid();
845
- items.push({ id, type, data: { ...data, ...initData }, children: childIds });
846
- return id;
847
- }
848
- /**
849
- * Synthetic loader data for Studio "section preview" mode. Mirrors Hydrogen's
850
- * `getPreviewData`: it builds a single-section page from the requested
851
- * `sectionType`'s presets without hitting `/api/public/project`, so preview
852
- * works even without a resolved `projectId`.
853
- */
854
- _generatePreviewData(projectId) {
855
- let { sectionType, weaverseHost } = this._baseConfigs;
856
- let items = [];
857
- let sectionId = sectionType ? this._buildPreviewItems(sectionType, items) : void 0;
858
- let configs = {
859
- ...this._buildPublicConfigs(projectId),
860
- isPreviewMode: true,
861
- weaverseHost,
862
- requestInfo: buildWeaverseNextRequestInfo(this.requestContext)
863
- };
864
- return {
865
- project: {
866
- id: projectId,
867
- weaverseShopId: "shop-id",
868
- name: "Section Preview"
869
- },
870
- configs,
871
- page: {
872
- id: "weaverse-preview-page",
873
- name: "Preview section",
874
- rootId: "1",
875
- items: [
876
- {
877
- id: "1",
878
- type: "main",
879
- data: {},
880
- children: sectionId ? [{ id: sectionId }] : []
881
- },
882
- ...items
883
- ]
884
- }
885
- };
886
- }
887
- _getLoadPageInput(input) {
888
- let {
889
- cache,
890
- projectId: routeProjectId,
891
- ...rest
892
- } = input;
893
- let params = {};
894
- for (let [key, value] of Object.entries(rest)) {
895
- if (value !== void 0) {
896
- params[key] = value;
897
- }
898
- }
899
- return { cache, params, routeProjectId };
900
- }
901
- async _resolveLoadPageProjectId(routeProjectId) {
902
- let effectiveProjectId = typeof routeProjectId === "string" && routeProjectId.trim() || await this.resolveProjectId();
903
- if (effectiveProjectId) {
904
- this.configs = this._buildPublicConfigs(effectiveProjectId);
905
- }
906
- return effectiveProjectId;
907
- }
908
- _fetchPagePayload(projectId, params, cache) {
909
- let i18n = this.requestContext?.i18n ?? this.commerce?.storefront?.i18n;
910
- let url = normalizeNextPageUrl(resolveRequestUrl(this.requestContext));
911
- let apiUrl = `${this._baseConfigs.weaverseApiBase}/api/public/project`;
912
- let userAgent = this.requestContext?.headers?.get("user-agent") ?? "";
913
- return this.fetchWithCache(apiUrl, {
914
- method: "POST",
915
- body: JSON.stringify({
916
- projectId,
917
- url,
918
- i18n,
919
- params,
920
- isDesignMode: this._baseConfigs.isDesignMode
921
- }),
922
- headers: { ...JSON_HEADERS, "X-Visitor-UA": userAgent },
923
- ...cache ?? {}
924
- });
925
- }
926
- _assertNoPageError(payload) {
927
- if ("error" in payload && typeof payload.error === "string") {
928
- throw new Error(payload.error);
929
- }
930
- }
931
- _createLoaderData(payload, projectId) {
932
- this._assertNoPageError(payload);
933
- let page = payload.page;
934
- let project = payload.project;
935
- let pageAssignment = normalizeWeaverseNextPageAssignment(
936
- payload.pageAssignment
937
- );
938
- page ??= this._generateFallbackPage(
939
- '<div style="text-align: center;">Please add new section to start.</div>'
940
- );
941
- project ??= {
942
- id: projectId,
943
- name: "Weaverse project not found.",
944
- weaverseShopId: ""
945
- };
946
- if (Array.isArray(page.items) && page.items.length === 0) {
947
- page.items.push({
948
- type: "main",
949
- id: page.rootId || generateUuid(),
950
- data: {}
951
- });
952
- }
953
- return {
954
- page,
955
- project,
956
- pageAssignment,
957
- configs: {
958
- ...this._buildPublicConfigs(projectId),
959
- requestInfo: buildWeaverseNextRequestInfo(this.requestContext)
960
- }
961
- };
962
- }
963
- async _runLoaders(data) {
964
- this.data = data;
965
- let withLoaders = await runWeaverseComponentLoaders({ client: this, data });
966
- this.data = withLoaders ?? data;
967
- return this.data;
968
- }
969
- loadPage = async (input = {}) => {
970
- try {
971
- let { cache, params, routeProjectId } = this._getLoadPageInput(input);
972
- let projectId = await this._resolveLoadPageProjectId(routeProjectId);
973
- if (this._baseConfigs.isPreviewMode) {
974
- let previewData = this._generatePreviewData(projectId || "x");
975
- this.data = previewData;
976
- return previewData;
977
- }
978
- if (!projectId) {
979
- throw new Error("Missing Weaverse projectId!");
980
- }
981
- let payload = await this._fetchPagePayload(projectId, params, cache);
982
- let data = this._createLoaderData(payload, projectId);
983
- return await this._runLoaders(data);
984
- } catch (error) {
985
- console.error("\u274C Page load failed", {
986
- url: this.requestContext?.url,
987
- projectId: input.projectId || this.configs.projectId,
988
- message: error instanceof Error ? error.message : String(error)
989
- });
990
- return null;
991
- }
992
- };
993
- /**
994
- * Resolve the request locale (e.g. `fr-ca`) used for merchant overrides.
995
- * Unlike Hydrogen — which defaults to `en`/`us` because a Hydrogen
996
- * storefront always has an i18n context — Next apps may not thread one
997
- * through, so a missing language or country means "no explicit locale" and
998
- * the translation fetch is skipped rather than guessed.
999
- */
1000
- _resolveOverridesLocale() {
1001
- let i18n = this.requestContext?.i18n;
1002
- let language = typeof i18n?.language === "string" ? i18n.language.trim() : "";
1003
- let country = typeof i18n?.country === "string" ? i18n.country.trim() : "";
1004
- if (!(language && country)) {
1005
- return;
1006
- }
1007
- return `${language.toLowerCase()}-${country.toLowerCase()}`;
1008
- }
1009
- /**
1010
- * Fetch locale-specific static-text overrides from the translation API.
1011
- * Ported from Hydrogen's `fetchMerchantOverrides`: skipped entirely when the
1012
- * theme has no `i18n` schema (nothing translatable) or when the request has
1013
- * no explicit locale, and never allowed to fail theme settings.
1014
- */
1015
- async _fetchMerchantOverrides(projectId, options) {
1016
- let { weaverseHost } = this._baseConfigs;
1017
- if (!(asThemeSchema(this.themeSchema)?.i18n && projectId && weaverseHost)) {
1018
- return;
1019
- }
1020
- let locale = this._resolveOverridesLocale();
1021
- if (!locale) {
1022
- return;
1023
- }
1024
- let url = `${weaverseHost}/api/translation/static?projectId=${projectId}&locale=${locale}`;
1025
- try {
1026
- let overrides = await this.fetchWithCache(url, {
1027
- method: "GET",
1028
- headers: { Accept: "application/json" },
1029
- revalidate: options.revalidate,
1030
- tags: options.tags
1031
- });
1032
- return typeof overrides === "object" && overrides !== null ? overrides : void 0;
1033
- } catch (error) {
1034
- console.warn(
1035
- "[WeaverseNext] Unable to load merchant overrides, using theme defaults:",
1036
- error instanceof Error ? error.message : String(error)
1037
- );
1038
- return;
1039
- }
1040
- }
1041
- loadThemeSettings = async (optionsInput = {}) => {
1042
- let options = optionsInput;
1043
- let themeSchema = asThemeSchema(this.themeSchema);
1044
- let defaultThemeSettings = generateDataFromSchema(this.themeSchema);
1045
- let staticContent = themeSchema?.i18n?.staticContent;
1046
- try {
1047
- let projectId = await this.resolveProjectId();
1048
- if (!projectId) {
1049
- throw new Error("Missing Weaverse projectId!");
1050
- }
1051
- let { isDesignMode } = this._baseConfigs;
1052
- let url = `${this._baseConfigs.weaverseApiBase}/api/public/project_configs`;
1053
- let [result, merchantOverrides] = await Promise.all([
1054
- this.fetchWithCache(url, {
1055
- method: "POST",
1056
- body: JSON.stringify({ projectId, isDesignMode }),
1057
- headers: JSON_HEADERS,
1058
- revalidate: options.revalidate,
1059
- tags: options.tags
1060
- }),
1061
- this._fetchMerchantOverrides(projectId, options)
1062
- ]);
1063
- if (typeof result !== "object" || result === null) {
1064
- result = { theme: defaultThemeSettings };
1065
- }
1066
- if (themeSchema?.settings || themeSchema?.inspector) {
1067
- if (!result.theme || typeof result.theme !== "object") {
1068
- result.theme = defaultThemeSettings;
1069
- } else {
1070
- result.theme = { ...defaultThemeSettings, ...result.theme };
1071
- }
1072
- }
1073
- if (staticContent) {
1074
- result.staticContent = staticContent;
1075
- }
1076
- if (merchantOverrides) {
1077
- result.merchantOverrides = merchantOverrides;
1078
- }
1079
- if (isDesignMode) {
1080
- let serializableSchema = themeSchema ? {
1081
- ...themeSchema,
1082
- settings: themeSchema.settings?.map((group) => ({
1083
- ...group,
1084
- inputs: group?.inputs?.map(
1085
- (inputItem) => typeof inputItem?.condition === "function" ? {
1086
- ...inputItem,
1087
- condition: inputItem.condition.toString()
1088
- } : inputItem
1089
- )
1090
- }))
1091
- } : void 0;
1092
- result = {
1093
- ...result,
1094
- schema: serializableSchema,
1095
- publicEnv: this._baseConfigs.publicEnv
1096
- };
1097
- }
1098
- return result;
1099
- } catch (error) {
1100
- let errorDetails = error instanceof Error ? error.message : String(error);
1101
- console.error("Unable to load theme settings", errorDetails);
1102
- return {
1103
- theme: defaultThemeSettings,
1104
- staticContent,
1105
- _error: errorDetails,
1106
- _loadFailed: true
1107
- };
1108
- }
1109
- };
284
+ components;
285
+ commerce;
286
+ requestContext;
287
+ themeSchema;
288
+ themeSettings;
289
+ data = null;
290
+ dataContext = {};
291
+ configs;
292
+ _projectIdInput;
293
+ _baseConfigs;
294
+ _fetch;
295
+ _cache;
296
+ _fetchTimeoutMs;
297
+ _resolvedProjectId;
298
+ constructor(config) {
299
+ this.components = config.components;
300
+ this.commerce = config.commerce;
301
+ this.requestContext = config.requestContext;
302
+ this.themeSchema = config.themeSchema;
303
+ this.themeSettings = {
304
+ ...require_seo.generateDataFromSchema(config.themeSchema),
305
+ ...config.themeSettings
306
+ };
307
+ this._projectIdInput = config.projectId;
308
+ this._fetch = config.fetch ?? globalThis.fetch;
309
+ this._cache = config.cache;
310
+ this._fetchTimeoutMs = config.fetchTimeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS;
311
+ this._baseConfigs = getWeaverseNextConfigs(config.requestContext, {
312
+ env: config.env,
313
+ weaverseHost: config.weaverseHost,
314
+ weaverseApiBase: config.weaverseApiBase,
315
+ weaverseVersion: config.weaverseVersion
316
+ });
317
+ this.configs = this._buildPublicConfigs(this._baseConfigs.queryProjectId || (typeof this._projectIdInput === "string" ? this._projectIdInput.trim() : "") || this._baseConfigs.envProjectId);
318
+ }
319
+ get projectId() {
320
+ return this.configs.projectId;
321
+ }
322
+ get storefront() {
323
+ return this.commerce?.storefront;
324
+ }
325
+ _buildPublicConfigs(projectId) {
326
+ let base = this._baseConfigs;
327
+ return {
328
+ projectId,
329
+ weaverseHost: base.weaverseHost,
330
+ weaverseApiBase: base.weaverseApiBase,
331
+ weaversePublicApiBase: base.weaverseApiBase,
332
+ weaverseVersion: base.weaverseVersion,
333
+ isDesignMode: base.isDesignMode,
334
+ isPreviewMode: base.isPreviewMode,
335
+ isRevisionPreview: base.isRevisionPreview,
336
+ sectionType: base.sectionType,
337
+ publicEnv: base.publicEnv
338
+ };
339
+ }
340
+ resolveProjectId = async () => {
341
+ if (this._resolvedProjectId !== void 0) return this._resolvedProjectId;
342
+ let resolved = this._baseConfigs.queryProjectId;
343
+ if (!resolved && typeof this._projectIdInput === "function") try {
344
+ let value = await this._projectIdInput(this.requestContext);
345
+ if (typeof value === "string" && value.trim()) resolved = value.trim();
346
+ } catch (error) {
347
+ console.warn("[WeaverseNextServerClient] projectId resolver threw, falling back.", error);
348
+ }
349
+ if (!resolved && typeof this._projectIdInput === "string") resolved = this._projectIdInput.trim();
350
+ if (!resolved) resolved = this._baseConfigs.envProjectId;
351
+ this._resolvedProjectId = resolved;
352
+ this.configs = this._buildPublicConfigs(resolved);
353
+ return resolved;
354
+ };
355
+ fetchWithCache = async (url, options = {}) => {
356
+ let { revalidate, tags, ...init } = options;
357
+ let requestInit = { ...init };
358
+ let { isDesignMode, isRevisionPreview } = this._baseConfigs;
359
+ if (isDesignMode || isRevisionPreview) requestInit.cache = "no-store";
360
+ else if (requestInit.cache === void 0) {
361
+ let effectiveRevalidate = revalidate ?? this._cache?.revalidate;
362
+ let effectiveTags = tags ?? this._cache?.tags;
363
+ if (effectiveRevalidate !== void 0 || effectiveTags?.length) requestInit.next = {
364
+ ...effectiveRevalidate === void 0 ? {} : { revalidate: effectiveRevalidate },
365
+ ...effectiveTags?.length ? { tags: effectiveTags } : {}
366
+ };
367
+ }
368
+ let controller = new AbortController();
369
+ let timeoutId = setTimeout(() => controller.abort(), this._fetchTimeoutMs);
370
+ try {
371
+ let response = await this._fetch(url, {
372
+ ...requestInit,
373
+ signal: requestInit.signal ?? controller.signal
374
+ });
375
+ if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);
376
+ return await response.json();
377
+ } finally {
378
+ clearTimeout(timeoutId);
379
+ }
380
+ };
381
+ _buildCustomPagesUrl(projectId, options, cursor) {
382
+ let params = new URLSearchParams();
383
+ if (options.locale) params.set("locale", options.locale);
384
+ if (options.limit) params.set("limit", String(options.limit));
385
+ if (cursor) params.set("cursor", cursor);
386
+ let qs = params.toString();
387
+ return `${this._baseConfigs.weaverseApiBase}/api/public/v1/projects/${projectId}/custom-pages${qs ? `?${qs}` : ""}`;
388
+ }
389
+ fetchCustomPages = async (options = {}) => {
390
+ let projectId = await this.resolveProjectId();
391
+ let entries = [];
392
+ if (!projectId) {
393
+ console.warn("[WeaverseNext] Failed to fetch custom pages: missing projectId");
394
+ return entries;
395
+ }
396
+ let cursor = null;
397
+ for (let page = 0; page < MAX_CUSTOM_PAGE_PAGES; page += 1) {
398
+ let url = this._buildCustomPagesUrl(projectId, options, cursor);
399
+ try {
400
+ let result = await this.fetchWithCache(url, {
401
+ revalidate: options.revalidate,
402
+ tags: options.tags
403
+ });
404
+ entries.push(...result.data ?? []);
405
+ if (!result.nextCursor) return entries;
406
+ cursor = result.nextCursor;
407
+ } catch (error) {
408
+ let message = error instanceof Error ? error.message : String(error);
409
+ console.warn(entries.length === 0 ? `[WeaverseNext] Failed to fetch custom pages: ${message}` : `[WeaverseNext] Custom pages pagination interrupted: ${message}`);
410
+ return entries;
411
+ }
412
+ }
413
+ console.warn("[WeaverseNext] Custom pages pagination cap reached");
414
+ return entries;
415
+ };
416
+ _generateFallbackPage(message) {
417
+ let rootId = generateUuid();
418
+ return {
419
+ id: `fallback_page_${rootId}`,
420
+ rootId,
421
+ name: "Default Page",
422
+ items: [{
423
+ type: "main",
424
+ id: rootId,
425
+ data: { dangerouslySetInnerHTML: { __html: message } }
426
+ }]
427
+ };
428
+ }
429
+ _buildPreviewItems(type, items, initData = {}) {
430
+ let component = this.components.find((c) => c.schema?.type === type);
431
+ if (!component) return;
432
+ let { children, ...data } = component.schema?.presets ?? {};
433
+ let childIds = [];
434
+ if (children) for (let child of children) {
435
+ let { type: childType, children: _children, ...childData } = child;
436
+ let childId = this._buildPreviewItems(childType, items, childData);
437
+ if (childId) childIds.push({ id: childId });
438
+ }
439
+ let id = generateUuid();
440
+ items.push({
441
+ id,
442
+ type,
443
+ data: {
444
+ ...data,
445
+ ...initData
446
+ },
447
+ children: childIds
448
+ });
449
+ return id;
450
+ }
451
+ _generatePreviewData(projectId) {
452
+ let { sectionType, weaverseHost } = this._baseConfigs;
453
+ let items = [];
454
+ let sectionId = sectionType ? this._buildPreviewItems(sectionType, items) : void 0;
455
+ let configs = {
456
+ ...this._buildPublicConfigs(projectId),
457
+ isPreviewMode: true,
458
+ weaverseHost,
459
+ requestInfo: require_seo.buildWeaverseNextRequestInfo(this.requestContext)
460
+ };
461
+ return {
462
+ project: {
463
+ id: projectId,
464
+ weaverseShopId: "shop-id",
465
+ name: "Section Preview"
466
+ },
467
+ configs,
468
+ page: {
469
+ id: "weaverse-preview-page",
470
+ name: "Preview section",
471
+ rootId: "1",
472
+ items: [{
473
+ id: "1",
474
+ type: "main",
475
+ data: {},
476
+ children: sectionId ? [{ id: sectionId }] : []
477
+ }, ...items]
478
+ }
479
+ };
480
+ }
481
+ _getLoadPageInput(input) {
482
+ let { cache, projectId: routeProjectId, ...rest } = input;
483
+ let params = {};
484
+ for (let [key, value] of Object.entries(rest)) if (value !== void 0) params[key] = value;
485
+ return {
486
+ cache,
487
+ params,
488
+ routeProjectId
489
+ };
490
+ }
491
+ async _resolveLoadPageProjectId(routeProjectId) {
492
+ let effectiveProjectId = typeof routeProjectId === "string" && routeProjectId.trim() || await this.resolveProjectId();
493
+ if (effectiveProjectId) this.configs = this._buildPublicConfigs(effectiveProjectId);
494
+ return effectiveProjectId;
495
+ }
496
+ _fetchPagePayload(projectId, params, cache) {
497
+ let i18n = this.requestContext?.i18n ?? this.commerce?.storefront?.i18n;
498
+ let url = normalizeNextPageUrl(resolveRequestUrl(this.requestContext));
499
+ let apiUrl = `${this._baseConfigs.weaverseApiBase}/api/public/project`;
500
+ let userAgent = this.requestContext?.headers?.get("user-agent") ?? "";
501
+ return this.fetchWithCache(apiUrl, {
502
+ method: "POST",
503
+ body: JSON.stringify({
504
+ projectId,
505
+ url,
506
+ i18n,
507
+ params,
508
+ isDesignMode: this._baseConfigs.isDesignMode
509
+ }),
510
+ headers: {
511
+ ...JSON_HEADERS,
512
+ "X-Visitor-UA": userAgent
513
+ },
514
+ ...cache ?? {}
515
+ });
516
+ }
517
+ _assertNoPageError(payload) {
518
+ if ("error" in payload && typeof payload.error === "string") throw new Error(payload.error);
519
+ }
520
+ _createLoaderData(payload, projectId) {
521
+ this._assertNoPageError(payload);
522
+ let page = payload.page;
523
+ let project = payload.project;
524
+ let pageAssignment = normalizeWeaverseNextPageAssignment(payload.pageAssignment);
525
+ page ??= this._generateFallbackPage("<div style=\"text-align: center;\">Please add new section to start.</div>");
526
+ project ??= {
527
+ id: projectId,
528
+ name: "Weaverse project not found.",
529
+ weaverseShopId: ""
530
+ };
531
+ if (Array.isArray(page.items) && page.items.length === 0) page.items.push({
532
+ type: "main",
533
+ id: page.rootId || generateUuid(),
534
+ data: {}
535
+ });
536
+ return {
537
+ page,
538
+ project,
539
+ pageAssignment,
540
+ configs: {
541
+ ...this._buildPublicConfigs(projectId),
542
+ requestInfo: require_seo.buildWeaverseNextRequestInfo(this.requestContext)
543
+ }
544
+ };
545
+ }
546
+ async _runLoaders(data) {
547
+ this.data = data;
548
+ let withLoaders = await require_seo.runWeaverseComponentLoaders({
549
+ client: this,
550
+ data
551
+ });
552
+ this.data = withLoaders ?? data;
553
+ return this.data;
554
+ }
555
+ loadPage = async (input = {}) => {
556
+ try {
557
+ let { cache, params, routeProjectId } = this._getLoadPageInput(input);
558
+ let projectId = await this._resolveLoadPageProjectId(routeProjectId);
559
+ if (this._baseConfigs.isPreviewMode) {
560
+ let previewData = this._generatePreviewData(projectId || "x");
561
+ this.data = previewData;
562
+ return previewData;
563
+ }
564
+ if (!projectId) throw new Error("Missing Weaverse projectId!");
565
+ let payload = await this._fetchPagePayload(projectId, params, cache);
566
+ let data = this._createLoaderData(payload, projectId);
567
+ return await this._runLoaders(data);
568
+ } catch (error) {
569
+ console.error("❌ Page load failed", {
570
+ url: this.requestContext?.url,
571
+ projectId: input.projectId || this.configs.projectId,
572
+ message: error instanceof Error ? error.message : String(error)
573
+ });
574
+ return null;
575
+ }
576
+ };
577
+ _resolveOverridesLocale() {
578
+ let i18n = this.requestContext?.i18n;
579
+ let language = typeof i18n?.language === "string" ? i18n.language.trim() : "";
580
+ let country = typeof i18n?.country === "string" ? i18n.country.trim() : "";
581
+ if (!(language && country)) return;
582
+ return `${language.toLowerCase()}-${country.toLowerCase()}`;
583
+ }
584
+ async _fetchMerchantOverrides(projectId, options) {
585
+ let { weaverseHost } = this._baseConfigs;
586
+ if (!(asThemeSchema(this.themeSchema)?.i18n && projectId && weaverseHost)) return;
587
+ let locale = this._resolveOverridesLocale();
588
+ if (!locale) return;
589
+ let url = `${weaverseHost}/api/translation/static?projectId=${projectId}&locale=${locale}`;
590
+ try {
591
+ let overrides = await this.fetchWithCache(url, {
592
+ method: "GET",
593
+ headers: { Accept: "application/json" },
594
+ revalidate: options.revalidate,
595
+ tags: options.tags
596
+ });
597
+ return typeof overrides === "object" && overrides !== null ? overrides : void 0;
598
+ } catch (error) {
599
+ console.warn("[WeaverseNext] Unable to load merchant overrides, using theme defaults:", error instanceof Error ? error.message : String(error));
600
+ return;
601
+ }
602
+ }
603
+ loadThemeSettings = async (optionsInput = {}) => {
604
+ let options = optionsInput;
605
+ let themeSchema = asThemeSchema(this.themeSchema);
606
+ let defaultThemeSettings = require_seo.generateDataFromSchema(this.themeSchema);
607
+ let staticContent = themeSchema?.i18n?.staticContent;
608
+ try {
609
+ let projectId = await this.resolveProjectId();
610
+ if (!projectId) throw new Error("Missing Weaverse projectId!");
611
+ let { isDesignMode } = this._baseConfigs;
612
+ let url = `${this._baseConfigs.weaverseApiBase}/api/public/project_configs`;
613
+ let [result, merchantOverrides] = await Promise.all([this.fetchWithCache(url, {
614
+ method: "POST",
615
+ body: JSON.stringify({
616
+ projectId,
617
+ isDesignMode
618
+ }),
619
+ headers: JSON_HEADERS,
620
+ revalidate: options.revalidate,
621
+ tags: options.tags
622
+ }), this._fetchMerchantOverrides(projectId, options)]);
623
+ if (typeof result !== "object" || result === null) result = { theme: defaultThemeSettings };
624
+ if (themeSchema?.settings || themeSchema?.inspector) if (!result.theme || typeof result.theme !== "object") result.theme = defaultThemeSettings;
625
+ else result.theme = {
626
+ ...defaultThemeSettings,
627
+ ...result.theme
628
+ };
629
+ if (staticContent) result.staticContent = staticContent;
630
+ if (merchantOverrides) result.merchantOverrides = merchantOverrides;
631
+ if (isDesignMode) {
632
+ let serializableSchema = themeSchema ? {
633
+ ...themeSchema,
634
+ settings: themeSchema.settings?.map((group) => ({
635
+ ...group,
636
+ inputs: group?.inputs?.map((inputItem) => typeof inputItem?.condition === "function" ? {
637
+ ...inputItem,
638
+ condition: inputItem.condition.toString()
639
+ } : inputItem)
640
+ }))
641
+ } : void 0;
642
+ result = {
643
+ ...result,
644
+ schema: serializableSchema,
645
+ publicEnv: this._baseConfigs.publicEnv
646
+ };
647
+ }
648
+ return result;
649
+ } catch (error) {
650
+ let errorDetails = error instanceof Error ? error.message : String(error);
651
+ console.error("Unable to load theme settings", errorDetails);
652
+ return {
653
+ theme: defaultThemeSettings,
654
+ staticContent,
655
+ _error: errorDetails,
656
+ _loadFailed: true
657
+ };
658
+ }
659
+ };
1110
660
  };
1111
661
  function createWeaverseNextServerClient(config) {
1112
- return new NextServerClient(config);
662
+ return new NextServerClient(config);
1113
663
  }
1114
-
664
+ //#endregion
1115
665
  exports.createWeaverseNextRevalidateHandler = createWeaverseNextRevalidateHandler;
1116
666
  exports.createWeaverseNextServerClient = createWeaverseNextServerClient;
1117
- exports.formatWeaverseNextSeoMetadata = formatWeaverseNextSeoMetadata;
667
+ exports.formatWeaverseNextSeoMetadata = require_seo.formatWeaverseNextSeoMetadata;
1118
668
  exports.getWeaverseNextConfigs = getWeaverseNextConfigs;
1119
- exports.getWeaverseNextSeoMetadata = getWeaverseNextSeoMetadata;
669
+ exports.getWeaverseNextSeoMetadata = require_seo.getWeaverseNextSeoMetadata;
1120
670
  exports.normalizeNextPageUrl = normalizeNextPageUrl;
1121
671
  exports.resolveRequestUrl = resolveRequestUrl;
1122
- //# sourceMappingURL=server.js.map
672
+
1123
673
  //# sourceMappingURL=server.js.map