@weaverse/next 1.0.1 → 1.0.2
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/dist/client-boundary.js +929 -1293
- package/dist/client-boundary.js.map +1 -1
- package/dist/client-boundary.mjs +902 -1280
- package/dist/client-boundary.mjs.map +1 -1
- package/dist/index.js +265 -576
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +139 -175
- package/dist/index.mjs.map +1 -1
- package/dist/seo-BCFNGChj.js +319 -0
- package/dist/seo-BCFNGChj.js.map +1 -0
- package/dist/seo-C-S2viuI.mjs +242 -0
- package/dist/seo-C-S2viuI.mjs.map +1 -0
- package/dist/server.js +626 -1076
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +620 -803
- package/dist/server.mjs.map +1 -1
- package/dist/types/item.d.ts +1 -1
- package/dist/types/item.d.ts.map +1 -1
- package/dist/types/revalidate-item.d.ts +1 -1
- package/dist/types/revalidate-item.d.ts.map +1 -1
- package/dist/types/runtime.d.ts.map +1 -1
- package/dist/types/translation-store.d.ts.map +1 -1
- package/dist/types/types.d.ts +6 -1
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/types.ts +6 -0
- package/dist/chunk-OSC5HR5V.mjs +0 -328
- package/dist/chunk-OSC5HR5V.mjs.map +0 -1
package/dist/server.js
CHANGED
|
@@ -1,1123 +1,673 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
-
|
|
110
|
-
|
|
35
|
+
let values = searchParams.getAll(key);
|
|
36
|
+
return values.length ? values.at(-1) : void 0;
|
|
111
37
|
}
|
|
112
38
|
function coerceBool(value) {
|
|
113
|
-
|
|
39
|
+
return value === "true";
|
|
114
40
|
}
|
|
115
41
|
function readEnv(env, key) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
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
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
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
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
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
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
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
|
-
|
|
348
|
-
|
|
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
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
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
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
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
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
196
|
+
return new Response(JSON.stringify(body), {
|
|
197
|
+
status,
|
|
198
|
+
headers: NO_STORE_HEADERS
|
|
199
|
+
});
|
|
444
200
|
}
|
|
445
201
|
function parseDraftItem(payload) {
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
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
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
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
|
-
|
|
264
|
+
return schema && typeof schema === "object" ? schema : void 0;
|
|
610
265
|
}
|
|
611
266
|
function generateUuid() {
|
|
612
|
-
|
|
613
|
-
|
|
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
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
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
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
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
|
-
|
|
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
|
-
|
|
672
|
+
|
|
1123
673
|
//# sourceMappingURL=server.js.map
|