@weaverse/next 0.1.0-alpha.2 → 0.1.0-alpha.20
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/README.md +586 -123
- package/dist/chunk-LH6AAEIK.mjs +326 -0
- package/dist/chunk-LH6AAEIK.mjs.map +1 -0
- package/dist/index.js +784 -60
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +588 -58
- package/dist/index.mjs.map +1 -1
- package/dist/server.js +537 -76
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +363 -27
- package/dist/server.mjs.map +1 -1
- package/dist/types/client.d.ts +16 -0
- package/dist/types/client.d.ts.map +1 -0
- package/dist/types/hooks.d.ts +20 -0
- package/dist/types/hooks.d.ts.map +1 -0
- package/dist/types/index.d.ts +34 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/item.d.ts +60 -0
- package/dist/types/item.d.ts.map +1 -0
- package/dist/types/loader.d.ts +25 -0
- package/dist/types/loader.d.ts.map +1 -0
- package/dist/types/main.d.ts +11 -0
- package/dist/types/main.d.ts.map +1 -0
- package/dist/types/provider.d.ts +82 -0
- package/dist/types/provider.d.ts.map +1 -0
- package/dist/types/registry.d.ts +15 -0
- package/dist/types/registry.d.ts.map +1 -0
- package/dist/types/renderer.d.ts +21 -0
- package/dist/types/renderer.d.ts.map +1 -0
- package/dist/types/request-info.d.ts +19 -0
- package/dist/types/request-info.d.ts.map +1 -0
- package/dist/types/revalidate-item.d.ts +82 -0
- package/dist/types/revalidate-item.d.ts.map +1 -0
- package/dist/types/root-provider.d.ts +62 -0
- package/dist/types/root-provider.d.ts.map +1 -0
- package/dist/types/runtime.d.ts +113 -0
- package/dist/types/runtime.d.ts.map +1 -0
- package/dist/types/seo.d.ts +55 -0
- package/dist/types/seo.d.ts.map +1 -0
- package/dist/types/server/configs.d.ts +27 -0
- package/dist/types/server/configs.d.ts.map +1 -0
- package/dist/types/server/normalize-page-url.d.ts +19 -0
- package/dist/types/server/normalize-page-url.d.ts.map +1 -0
- package/dist/types/server/revalidate-handler.d.ts +55 -0
- package/dist/types/server/revalidate-handler.d.ts.map +1 -0
- package/dist/types/server/server-client.d.ts +21 -0
- package/dist/types/server/server-client.d.ts.map +1 -0
- package/dist/types/server.d.ts +19 -0
- package/dist/types/server.d.ts.map +1 -0
- package/dist/types/studio-bridge.d.ts +16 -0
- package/dist/types/studio-bridge.d.ts.map +1 -0
- package/dist/types/studio-connect.d.ts +27 -0
- package/dist/types/studio-connect.d.ts.map +1 -0
- package/dist/types/studio-router.d.ts +50 -0
- package/dist/types/studio-router.d.ts.map +1 -0
- package/dist/types/studio-script-src.d.ts +12 -0
- package/dist/types/studio-script-src.d.ts.map +1 -0
- package/dist/types/theme-settings-store.d.ts +18 -0
- package/dist/types/theme-settings-store.d.ts.map +1 -0
- package/dist/types/translation-context.d.ts +156 -0
- package/dist/types/translation-context.d.ts.map +1 -0
- package/dist/types/translation-store.d.ts +44 -0
- package/dist/types/translation-store.d.ts.map +1 -0
- package/dist/types/types.d.ts +665 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/use-weaverse-next-studio.d.ts +34 -0
- package/dist/types/use-weaverse-next-studio.d.ts.map +1 -0
- package/dist/types/utils.d.ts +12 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/package.json +12 -8
- package/src/client.ts +102 -0
- package/src/hooks.ts +50 -0
- package/src/index.ts +153 -0
- package/src/item.ts +167 -0
- package/src/loader.ts +135 -0
- package/src/main.tsx +45 -0
- package/src/provider.tsx +225 -0
- package/src/registry.ts +63 -0
- package/src/renderer.tsx +100 -0
- package/src/request-info.ts +124 -0
- package/src/revalidate-item.ts +211 -0
- package/src/root-provider.tsx +182 -0
- package/src/runtime.ts +555 -0
- package/src/seo.ts +157 -0
- package/src/server/configs.ts +178 -0
- package/src/server/normalize-page-url.ts +73 -0
- package/src/server/revalidate-handler.ts +357 -0
- package/src/server/server-client.ts +728 -0
- package/src/server.ts +67 -0
- package/src/studio-bridge.tsx +82 -0
- package/src/studio-connect.tsx +88 -0
- package/src/studio-router.ts +85 -0
- package/src/studio-script-src.ts +128 -0
- package/src/theme-settings-store.ts +47 -0
- package/src/translation-context.tsx +299 -0
- package/src/translation-store.ts +69 -0
- package/src/types.ts +753 -0
- package/src/use-weaverse-next-studio.tsx +106 -0
- package/src/utils.ts +37 -0
- package/dist/chunk-SS6QUKYY.mjs +0 -149
- package/dist/chunk-SS6QUKYY.mjs.map +0 -1
- package/dist/index.d.mts +0 -250
- package/dist/index.d.ts +0 -250
- package/dist/server.d.mts +0 -60
- package/dist/server.d.ts +0 -60
- package/dist/types-DvEeLX6L.d.mts +0 -321
- package/dist/types-DvEeLX6L.d.ts +0 -321
package/dist/server.mjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { generateDataFromSchema, buildWeaverseNextRequestInfo, runWeaverseComponentLoaders } from './chunk-
|
|
1
|
+
import { withPathPrefix, generateDataFromSchema, sanitizeRouteContextSearch, buildWeaverseNextRequestInfo, runWeaverseComponentLoaders, ROUTE_CONTEXT_I18N_KEYS } from './chunk-LH6AAEIK.mjs';
|
|
2
|
+
export { formatWeaverseNextSeoMetadata, getWeaverseNextSeoMetadata } from './chunk-LH6AAEIK.mjs';
|
|
3
|
+
import { PageTypeSchema } from '@weaverse/schema';
|
|
2
4
|
|
|
3
5
|
// src/server/configs.ts
|
|
4
6
|
var DEFAULT_WEAVERSE_HOST = "https://studio.weaverse.io";
|
|
@@ -71,7 +73,6 @@ function getWeaverseNextConfigs(context, options = {}) {
|
|
|
71
73
|
envProjectId: readEnv(env, "WEAVERSE_PROJECT_ID") || "",
|
|
72
74
|
weaverseHost,
|
|
73
75
|
weaverseApiBase,
|
|
74
|
-
weaverseApiKey: lastParam(searchParams, "weaverseApiKey") || readEnv(env, "WEAVERSE_API_KEY") || "",
|
|
75
76
|
weaverseVersion: lastParam(searchParams, "weaverseVersion") || options.weaverseVersion || "",
|
|
76
77
|
isDesignMode,
|
|
77
78
|
isPreviewMode,
|
|
@@ -85,7 +86,7 @@ function getWeaverseNextConfigs(context, options = {}) {
|
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
// src/server/normalize-page-url.ts
|
|
88
|
-
var KEPT_PARAM_RE = /^(?:__revisionId|isDesignMode|weaverse)/;
|
|
89
|
+
var KEPT_PARAM_RE = /^(?:__revisionId|__weaverseDraftItem|isDesignMode|weaverse)/;
|
|
89
90
|
var DATA_SUFFIX = ".data";
|
|
90
91
|
function normalizeNextPageUrl(url) {
|
|
91
92
|
let parsed;
|
|
@@ -109,17 +110,228 @@ function normalizeNextPageUrl(url) {
|
|
|
109
110
|
}
|
|
110
111
|
function resolveRequestUrl(context) {
|
|
111
112
|
if (context?.url) {
|
|
112
|
-
|
|
113
|
+
let raw = String(context.url);
|
|
114
|
+
let url = new URL(raw, "http://localhost");
|
|
115
|
+
let pathname2 = withPathPrefix(url.pathname, context.i18n);
|
|
116
|
+
if (pathname2 === url.pathname) {
|
|
117
|
+
return raw;
|
|
118
|
+
}
|
|
119
|
+
url.pathname = pathname2;
|
|
120
|
+
return url.toString();
|
|
113
121
|
}
|
|
114
|
-
let pathname = context?.pathname || "/";
|
|
122
|
+
let pathname = withPathPrefix(context?.pathname || "/", context?.i18n);
|
|
115
123
|
let search = context?.searchParams ? new URLSearchParams(context.searchParams).toString() : "";
|
|
116
124
|
return `http://localhost${pathname}${search ? `?${search}` : ""}`;
|
|
117
125
|
}
|
|
126
|
+
var NO_STORE_HEADERS = {
|
|
127
|
+
"Content-Type": "application/json",
|
|
128
|
+
"Cache-Control": "no-store"
|
|
129
|
+
};
|
|
130
|
+
var STATUS_OK = 200;
|
|
131
|
+
var STATUS_BAD_REQUEST = 400;
|
|
132
|
+
var STATUS_NOT_FOUND = 404;
|
|
133
|
+
var STATUS_UNPROCESSABLE = 422;
|
|
134
|
+
var STATUS_SERVER_ERROR = 500;
|
|
135
|
+
var MAX_PATHNAME_LENGTH = 2048;
|
|
136
|
+
var MAX_SEARCH_LENGTH = 8192;
|
|
137
|
+
var MAX_HANDLE_LENGTH = 512;
|
|
138
|
+
var MAX_I18N_FIELD_LENGTH = 256;
|
|
139
|
+
var CONTROL_CHAR_PATTERN = /[\u0000-\u001F\u007F]/;
|
|
140
|
+
function isValidPathname(pathname) {
|
|
141
|
+
if (!pathname || pathname.length > MAX_PATHNAME_LENGTH) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
if (pathname[0] !== "/" || pathname.startsWith("//")) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
if (pathname.includes("\\") || pathname.includes("?")) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
if (pathname.includes("#") || CONTROL_CHAR_PATTERN.test(pathname)) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
function isPlainObject(value) {
|
|
156
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
let proto = Object.getPrototypeOf(value);
|
|
160
|
+
return proto === Object.prototype || proto === null;
|
|
161
|
+
}
|
|
162
|
+
function sanitizeRouteContextI18n(input) {
|
|
163
|
+
if (input === void 0) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (!isPlainObject(input)) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
let source = input;
|
|
170
|
+
let allowed = new Set(ROUTE_CONTEXT_I18N_KEYS);
|
|
171
|
+
for (let key of Object.keys(source)) {
|
|
172
|
+
if (!allowed.has(key)) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
let result = {};
|
|
177
|
+
for (let key of ROUTE_CONTEXT_I18N_KEYS) {
|
|
178
|
+
let value = source[key];
|
|
179
|
+
if (value === void 0) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (typeof value !== "string" || value.length > MAX_I18N_FIELD_LENGTH) {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
result[key] = value;
|
|
186
|
+
}
|
|
187
|
+
return Object.keys(result).length ? result : void 0;
|
|
188
|
+
}
|
|
189
|
+
function reconstructRouteContext(request, routeContext) {
|
|
190
|
+
if (typeof routeContext !== "object" || routeContext === null || Array.isArray(routeContext)) {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
let { pathname, search, handle, pageType, i18n } = routeContext;
|
|
194
|
+
if (typeof pathname !== "string" || !isValidPathname(pathname)) {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
if (typeof search !== "string" || search.length > MAX_SEARCH_LENGTH) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
let rawSearch = search;
|
|
201
|
+
if (rawSearch.length && !rawSearch.startsWith("?")) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
let sanitizedI18n = sanitizeRouteContextI18n(i18n);
|
|
205
|
+
if (sanitizedI18n === null) {
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
let resolvedPageType;
|
|
209
|
+
if (pageType !== void 0) {
|
|
210
|
+
let parsed = PageTypeSchema.safeParse(pageType);
|
|
211
|
+
if (!parsed.success) {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
resolvedPageType = parsed.data;
|
|
215
|
+
}
|
|
216
|
+
let resolvedHandle;
|
|
217
|
+
if (handle !== void 0) {
|
|
218
|
+
if (typeof handle !== "string" || !handle || handle.length > MAX_HANDLE_LENGTH) {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
resolvedHandle = handle;
|
|
222
|
+
}
|
|
223
|
+
let endpointUrl = new URL(request.url);
|
|
224
|
+
let routeUrl = new URL(endpointUrl.origin);
|
|
225
|
+
routeUrl.pathname = pathname;
|
|
226
|
+
routeUrl.search = sanitizeRouteContextSearch(rawSearch);
|
|
227
|
+
let canonicalPathname = routeUrl.pathname;
|
|
228
|
+
let searchParams = routeUrl.searchParams;
|
|
229
|
+
let lastParam2 = (key) => {
|
|
230
|
+
let values = searchParams.getAll(key);
|
|
231
|
+
return values.length ? values.at(-1) : void 0;
|
|
232
|
+
};
|
|
233
|
+
return {
|
|
234
|
+
pathname: canonicalPathname,
|
|
235
|
+
searchParams,
|
|
236
|
+
url: routeUrl,
|
|
237
|
+
// Headers come from the actual same-origin POST, never its JSON body.
|
|
238
|
+
headers: new Headers(request.headers),
|
|
239
|
+
...sanitizedI18n ? { i18n: sanitizedI18n } : {},
|
|
240
|
+
...resolvedPageType ? { pageType: resolvedPageType } : {},
|
|
241
|
+
...resolvedHandle ? { handle: resolvedHandle } : {},
|
|
242
|
+
isDesignMode: lastParam2("isDesignMode") === "true",
|
|
243
|
+
isPreviewMode: lastParam2("isPreviewMode") === "true",
|
|
244
|
+
isRevisionPreview: searchParams.has("__revisionId"),
|
|
245
|
+
sectionType: lastParam2("sectionType") || void 0
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
function json(body, status) {
|
|
249
|
+
return new Response(JSON.stringify(body), {
|
|
250
|
+
status,
|
|
251
|
+
headers: NO_STORE_HEADERS
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
function parseDraftItem(payload) {
|
|
255
|
+
if (typeof payload !== "object" || payload === null) {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
let draftItem = payload.draftItem;
|
|
259
|
+
if (typeof draftItem !== "object" || draftItem === null) {
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
let { id, type } = draftItem;
|
|
263
|
+
if (typeof id !== "string" || !id || typeof type !== "string" || !type) {
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
return draftItem;
|
|
267
|
+
}
|
|
268
|
+
function createWeaverseNextRevalidateHandler(config) {
|
|
269
|
+
return {
|
|
270
|
+
POST: async (request) => {
|
|
271
|
+
let payload;
|
|
272
|
+
try {
|
|
273
|
+
payload = await request.json();
|
|
274
|
+
} catch {
|
|
275
|
+
return json({ error: "invalid-payload" }, STATUS_BAD_REQUEST);
|
|
276
|
+
}
|
|
277
|
+
let draftItem = parseDraftItem(payload);
|
|
278
|
+
if (!draftItem) {
|
|
279
|
+
return json({ error: "invalid-payload" }, STATUS_BAD_REQUEST);
|
|
280
|
+
}
|
|
281
|
+
let requestContext;
|
|
282
|
+
let body = payload;
|
|
283
|
+
if (Object.hasOwn(body, "routeContext")) {
|
|
284
|
+
let reconstructed = reconstructRouteContext(request, body.routeContext);
|
|
285
|
+
if (!reconstructed) {
|
|
286
|
+
return json({ error: "invalid-route-context" }, STATUS_BAD_REQUEST);
|
|
287
|
+
}
|
|
288
|
+
requestContext = reconstructed;
|
|
289
|
+
}
|
|
290
|
+
let client;
|
|
291
|
+
try {
|
|
292
|
+
client = await config.getClient(request, requestContext);
|
|
293
|
+
} catch (error) {
|
|
294
|
+
console.error("\u274C Revalidate handler getClient failed.", error);
|
|
295
|
+
return json({ error: "client-init-failed" }, STATUS_SERVER_ERROR);
|
|
296
|
+
}
|
|
297
|
+
let component = client.components.find(
|
|
298
|
+
(candidate) => candidate?.schema?.type === draftItem.type
|
|
299
|
+
);
|
|
300
|
+
if (!component) {
|
|
301
|
+
return json({ error: "unknown-component-type" }, STATUS_NOT_FOUND);
|
|
302
|
+
}
|
|
303
|
+
if (typeof component.loader !== "function") {
|
|
304
|
+
return json({ error: "missing-loader" }, STATUS_UNPROCESSABLE);
|
|
305
|
+
}
|
|
306
|
+
try {
|
|
307
|
+
let loaderData = await component.loader({
|
|
308
|
+
data: {
|
|
309
|
+
...generateDataFromSchema(component.schema),
|
|
310
|
+
...draftItem.data
|
|
311
|
+
},
|
|
312
|
+
weaverse: client,
|
|
313
|
+
context: client.requestContext,
|
|
314
|
+
commerce: client.commerce
|
|
315
|
+
});
|
|
316
|
+
return json({ loaderData: loaderData ?? null }, STATUS_OK);
|
|
317
|
+
} catch (error) {
|
|
318
|
+
console.error(
|
|
319
|
+
"\u274C Item loader revalidation failed.",
|
|
320
|
+
draftItem.type,
|
|
321
|
+
draftItem.id,
|
|
322
|
+
error
|
|
323
|
+
);
|
|
324
|
+
return json({ error: "loader-failed" }, STATUS_SERVER_ERROR);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
}
|
|
118
329
|
|
|
119
330
|
// src/server/server-client.ts
|
|
120
331
|
var DEFAULT_FETCH_TIMEOUT_MS = 1e4;
|
|
121
332
|
var RANDOM_ID_RADIX = 36;
|
|
122
333
|
var RANDOM_ID_SLICE_START = 2;
|
|
334
|
+
var MAX_CUSTOM_PAGE_PAGES = 100;
|
|
123
335
|
var JSON_HEADERS = {
|
|
124
336
|
"Content-Type": "application/json",
|
|
125
337
|
Accept: "application/json",
|
|
@@ -134,6 +346,25 @@ function generateUuid() {
|
|
|
134
346
|
}
|
|
135
347
|
return `id-${Math.random().toString(RANDOM_ID_RADIX).slice(RANDOM_ID_SLICE_START)}`;
|
|
136
348
|
}
|
|
349
|
+
function normalizeWeaverseNextPageAssignment(input) {
|
|
350
|
+
if (!input || typeof input !== "object") {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
let { projectId, type, handle, locale, meta } = input;
|
|
354
|
+
if (typeof projectId !== "string" || typeof type !== "string" || typeof handle !== "string") {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
let normalized = {
|
|
358
|
+
projectId,
|
|
359
|
+
type,
|
|
360
|
+
handle,
|
|
361
|
+
locale: typeof locale === "string" ? locale : ""
|
|
362
|
+
};
|
|
363
|
+
if (meta && typeof meta === "object") {
|
|
364
|
+
normalized.meta = meta;
|
|
365
|
+
}
|
|
366
|
+
return normalized;
|
|
367
|
+
}
|
|
137
368
|
var NextServerClient = class {
|
|
138
369
|
components;
|
|
139
370
|
commerce;
|
|
@@ -253,6 +484,59 @@ var NextServerClient = class {
|
|
|
253
484
|
clearTimeout(timeoutId);
|
|
254
485
|
}
|
|
255
486
|
};
|
|
487
|
+
_buildCustomPagesUrl(projectId, options, cursor) {
|
|
488
|
+
let params = new URLSearchParams();
|
|
489
|
+
if (options.locale) {
|
|
490
|
+
params.set("locale", options.locale);
|
|
491
|
+
}
|
|
492
|
+
if (options.limit) {
|
|
493
|
+
params.set("limit", String(options.limit));
|
|
494
|
+
}
|
|
495
|
+
if (cursor) {
|
|
496
|
+
params.set("cursor", cursor);
|
|
497
|
+
}
|
|
498
|
+
let qs = params.toString();
|
|
499
|
+
return `${this._baseConfigs.weaverseApiBase}/api/public/v1/projects/${projectId}/custom-pages${qs ? `?${qs}` : ""}`;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Fetch all published custom pages for sitemap generation. Mirrors Hydrogen's
|
|
503
|
+
* helper but uses Next's fetch cache knobs (`revalidate` / `tags`). It returns
|
|
504
|
+
* accumulated results on partial pagination failure so a single API hiccup
|
|
505
|
+
* does not break sitemap generation entirely.
|
|
506
|
+
*/
|
|
507
|
+
fetchCustomPages = async (options = {}) => {
|
|
508
|
+
let projectId = await this.resolveProjectId();
|
|
509
|
+
let entries = [];
|
|
510
|
+
if (!projectId) {
|
|
511
|
+
console.warn(
|
|
512
|
+
"[WeaverseNext] Failed to fetch custom pages: missing projectId"
|
|
513
|
+
);
|
|
514
|
+
return entries;
|
|
515
|
+
}
|
|
516
|
+
let cursor = null;
|
|
517
|
+
for (let page = 0; page < MAX_CUSTOM_PAGE_PAGES; page += 1) {
|
|
518
|
+
let url = this._buildCustomPagesUrl(projectId, options, cursor);
|
|
519
|
+
try {
|
|
520
|
+
let result = await this.fetchWithCache(url, {
|
|
521
|
+
revalidate: options.revalidate,
|
|
522
|
+
tags: options.tags
|
|
523
|
+
});
|
|
524
|
+
entries.push(...result.data ?? []);
|
|
525
|
+
if (!result.nextCursor) {
|
|
526
|
+
return entries;
|
|
527
|
+
}
|
|
528
|
+
cursor = result.nextCursor;
|
|
529
|
+
} catch (error) {
|
|
530
|
+
let message = error instanceof Error ? error.message : String(error);
|
|
531
|
+
console.warn(
|
|
532
|
+
entries.length === 0 ? `[WeaverseNext] Failed to fetch custom pages: ${message}` : `[WeaverseNext] Custom pages pagination interrupted: ${message}`
|
|
533
|
+
);
|
|
534
|
+
return entries;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
console.warn("[WeaverseNext] Custom pages pagination cap reached");
|
|
538
|
+
return entries;
|
|
539
|
+
};
|
|
256
540
|
_generateFallbackPage(message) {
|
|
257
541
|
let rootId = generateUuid();
|
|
258
542
|
return {
|
|
@@ -380,7 +664,9 @@ var NextServerClient = class {
|
|
|
380
664
|
this._assertNoPageError(payload);
|
|
381
665
|
let page = payload.page;
|
|
382
666
|
let project = payload.project;
|
|
383
|
-
let pageAssignment =
|
|
667
|
+
let pageAssignment = normalizeWeaverseNextPageAssignment(
|
|
668
|
+
payload.pageAssignment
|
|
669
|
+
);
|
|
384
670
|
page ??= this._generateFallbackPage(
|
|
385
671
|
'<div style="text-align: center;">Please add new section to start.</div>'
|
|
386
672
|
);
|
|
@@ -436,12 +722,58 @@ var NextServerClient = class {
|
|
|
436
722
|
return null;
|
|
437
723
|
}
|
|
438
724
|
};
|
|
725
|
+
/**
|
|
726
|
+
* Resolve the request locale (e.g. `fr-ca`) used for merchant overrides.
|
|
727
|
+
* Unlike Hydrogen — which defaults to `en`/`us` because a Hydrogen
|
|
728
|
+
* storefront always has an i18n context — Next apps may not thread one
|
|
729
|
+
* through, so a missing language or country means "no explicit locale" and
|
|
730
|
+
* the translation fetch is skipped rather than guessed.
|
|
731
|
+
*/
|
|
732
|
+
_resolveOverridesLocale() {
|
|
733
|
+
let i18n = this.requestContext?.i18n;
|
|
734
|
+
let language = typeof i18n?.language === "string" ? i18n.language.trim() : "";
|
|
735
|
+
let country = typeof i18n?.country === "string" ? i18n.country.trim() : "";
|
|
736
|
+
if (!(language && country)) {
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
return `${language.toLowerCase()}-${country.toLowerCase()}`;
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* Fetch locale-specific static-text overrides from the translation API.
|
|
743
|
+
* Ported from Hydrogen's `fetchMerchantOverrides`: skipped entirely when the
|
|
744
|
+
* theme has no `i18n` schema (nothing translatable) or when the request has
|
|
745
|
+
* no explicit locale, and never allowed to fail theme settings.
|
|
746
|
+
*/
|
|
747
|
+
async _fetchMerchantOverrides(projectId, options) {
|
|
748
|
+
let { weaverseHost } = this._baseConfigs;
|
|
749
|
+
if (!(asThemeSchema(this.themeSchema)?.i18n && projectId && weaverseHost)) {
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
let locale = this._resolveOverridesLocale();
|
|
753
|
+
if (!locale) {
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
let url = `${weaverseHost}/api/translation/static?projectId=${projectId}&locale=${locale}`;
|
|
757
|
+
try {
|
|
758
|
+
let overrides = await this.fetchWithCache(url, {
|
|
759
|
+
method: "GET",
|
|
760
|
+
headers: { Accept: "application/json" },
|
|
761
|
+
revalidate: options.revalidate,
|
|
762
|
+
tags: options.tags
|
|
763
|
+
});
|
|
764
|
+
return typeof overrides === "object" && overrides !== null ? overrides : void 0;
|
|
765
|
+
} catch (error) {
|
|
766
|
+
console.warn(
|
|
767
|
+
"[WeaverseNext] Unable to load merchant overrides, using theme defaults:",
|
|
768
|
+
error instanceof Error ? error.message : String(error)
|
|
769
|
+
);
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
439
773
|
loadThemeSettings = async (optionsInput = {}) => {
|
|
440
774
|
let options = optionsInput;
|
|
441
775
|
let themeSchema = asThemeSchema(this.themeSchema);
|
|
442
|
-
let defaultThemeSettings = generateDataFromSchema(
|
|
443
|
-
this.themeSchema
|
|
444
|
-
);
|
|
776
|
+
let defaultThemeSettings = generateDataFromSchema(this.themeSchema);
|
|
445
777
|
let staticContent = themeSchema?.i18n?.staticContent;
|
|
446
778
|
try {
|
|
447
779
|
let projectId = await this.resolveProjectId();
|
|
@@ -450,16 +782,16 @@ var NextServerClient = class {
|
|
|
450
782
|
}
|
|
451
783
|
let { isDesignMode } = this._baseConfigs;
|
|
452
784
|
let url = `${this._baseConfigs.weaverseApiBase}/api/public/project_configs`;
|
|
453
|
-
let result = await
|
|
454
|
-
url,
|
|
455
|
-
{
|
|
785
|
+
let [result, merchantOverrides] = await Promise.all([
|
|
786
|
+
this.fetchWithCache(url, {
|
|
456
787
|
method: "POST",
|
|
457
788
|
body: JSON.stringify({ projectId, isDesignMode }),
|
|
458
789
|
headers: JSON_HEADERS,
|
|
459
790
|
revalidate: options.revalidate,
|
|
460
791
|
tags: options.tags
|
|
461
|
-
}
|
|
462
|
-
|
|
792
|
+
}),
|
|
793
|
+
this._fetchMerchantOverrides(projectId, options)
|
|
794
|
+
]);
|
|
463
795
|
if (typeof result !== "object" || result === null) {
|
|
464
796
|
result = { theme: defaultThemeSettings };
|
|
465
797
|
}
|
|
@@ -473,21 +805,25 @@ var NextServerClient = class {
|
|
|
473
805
|
if (staticContent) {
|
|
474
806
|
result.staticContent = staticContent;
|
|
475
807
|
}
|
|
808
|
+
if (merchantOverrides) {
|
|
809
|
+
result.merchantOverrides = merchantOverrides;
|
|
810
|
+
}
|
|
476
811
|
if (isDesignMode) {
|
|
812
|
+
let serializableSchema = themeSchema ? {
|
|
813
|
+
...themeSchema,
|
|
814
|
+
settings: themeSchema.settings?.map((group) => ({
|
|
815
|
+
...group,
|
|
816
|
+
inputs: group?.inputs?.map(
|
|
817
|
+
(inputItem) => typeof inputItem?.condition === "function" ? {
|
|
818
|
+
...inputItem,
|
|
819
|
+
condition: inputItem.condition.toString()
|
|
820
|
+
} : inputItem
|
|
821
|
+
)
|
|
822
|
+
}))
|
|
823
|
+
} : void 0;
|
|
477
824
|
result = {
|
|
478
825
|
...result,
|
|
479
|
-
schema:
|
|
480
|
-
...themeSchema,
|
|
481
|
-
settings: themeSchema.settings?.map((group) => ({
|
|
482
|
-
...group,
|
|
483
|
-
inputs: group?.inputs?.map(
|
|
484
|
-
(inputItem) => typeof inputItem?.condition === "function" ? {
|
|
485
|
-
...inputItem,
|
|
486
|
-
condition: inputItem.condition.toString()
|
|
487
|
-
} : inputItem
|
|
488
|
-
)
|
|
489
|
-
}))
|
|
490
|
-
} : void 0,
|
|
826
|
+
schema: serializableSchema,
|
|
491
827
|
publicEnv: this._baseConfigs.publicEnv
|
|
492
828
|
};
|
|
493
829
|
}
|
|
@@ -508,6 +844,6 @@ function createWeaverseNextServerClient(config) {
|
|
|
508
844
|
return new NextServerClient(config);
|
|
509
845
|
}
|
|
510
846
|
|
|
511
|
-
export { createWeaverseNextServerClient, getWeaverseNextConfigs, normalizeNextPageUrl, resolveRequestUrl };
|
|
847
|
+
export { createWeaverseNextRevalidateHandler, createWeaverseNextServerClient, getWeaverseNextConfigs, normalizeNextPageUrl, resolveRequestUrl };
|
|
512
848
|
//# sourceMappingURL=server.mjs.map
|
|
513
849
|
//# sourceMappingURL=server.mjs.map
|