@weaverse/next 0.1.0-alpha.8 → 1.0.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 (106) hide show
  1. package/README.md +155 -73
  2. package/dist/{chunk-6PMZ77RA.mjs → chunk-LH6AAEIK.mjs} +115 -8
  3. package/dist/chunk-LH6AAEIK.mjs.map +1 -0
  4. package/dist/index.js +260 -30
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +167 -46
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/server.js +321 -91
  9. package/dist/server.js.map +1 -1
  10. package/dist/server.mjs +205 -28
  11. package/dist/server.mjs.map +1 -1
  12. package/dist/types/client.d.ts +16 -0
  13. package/dist/types/client.d.ts.map +1 -0
  14. package/dist/types/hooks.d.ts +20 -0
  15. package/dist/types/hooks.d.ts.map +1 -0
  16. package/dist/types/index.d.ts +34 -0
  17. package/dist/types/index.d.ts.map +1 -0
  18. package/dist/types/item.d.ts +60 -0
  19. package/dist/types/item.d.ts.map +1 -0
  20. package/dist/types/loader.d.ts +25 -0
  21. package/dist/types/loader.d.ts.map +1 -0
  22. package/dist/types/main.d.ts +11 -0
  23. package/dist/types/main.d.ts.map +1 -0
  24. package/dist/types/provider.d.ts +82 -0
  25. package/dist/types/provider.d.ts.map +1 -0
  26. package/dist/types/registry.d.ts +15 -0
  27. package/dist/types/registry.d.ts.map +1 -0
  28. package/dist/types/renderer.d.ts +21 -0
  29. package/dist/types/renderer.d.ts.map +1 -0
  30. package/dist/types/request-info.d.ts +19 -0
  31. package/dist/types/request-info.d.ts.map +1 -0
  32. package/dist/types/revalidate-item.d.ts +82 -0
  33. package/dist/types/revalidate-item.d.ts.map +1 -0
  34. package/dist/types/root-provider.d.ts +62 -0
  35. package/dist/types/root-provider.d.ts.map +1 -0
  36. package/dist/types/runtime.d.ts +113 -0
  37. package/dist/types/runtime.d.ts.map +1 -0
  38. package/dist/types/seo.d.ts +55 -0
  39. package/dist/types/seo.d.ts.map +1 -0
  40. package/dist/types/server/configs.d.ts +27 -0
  41. package/dist/types/server/configs.d.ts.map +1 -0
  42. package/dist/types/server/normalize-page-url.d.ts +19 -0
  43. package/dist/types/server/normalize-page-url.d.ts.map +1 -0
  44. package/dist/types/server/revalidate-handler.d.ts +55 -0
  45. package/dist/types/server/revalidate-handler.d.ts.map +1 -0
  46. package/dist/types/server/server-client.d.ts +21 -0
  47. package/dist/types/server/server-client.d.ts.map +1 -0
  48. package/dist/types/server.d.ts +19 -0
  49. package/dist/types/server.d.ts.map +1 -0
  50. package/dist/types/studio-bridge.d.ts +16 -0
  51. package/dist/types/studio-bridge.d.ts.map +1 -0
  52. package/dist/types/studio-connect.d.ts +27 -0
  53. package/dist/types/studio-connect.d.ts.map +1 -0
  54. package/dist/types/studio-router.d.ts +50 -0
  55. package/dist/types/studio-router.d.ts.map +1 -0
  56. package/dist/types/studio-script-src.d.ts +12 -0
  57. package/dist/types/studio-script-src.d.ts.map +1 -0
  58. package/dist/types/theme-settings-store.d.ts +18 -0
  59. package/dist/types/theme-settings-store.d.ts.map +1 -0
  60. package/dist/types/translation-context.d.ts +156 -0
  61. package/dist/types/translation-context.d.ts.map +1 -0
  62. package/dist/types/translation-store.d.ts +44 -0
  63. package/dist/types/translation-store.d.ts.map +1 -0
  64. package/dist/types/types.d.ts +665 -0
  65. package/dist/types/types.d.ts.map +1 -0
  66. package/dist/types/use-weaverse-next-studio.d.ts +34 -0
  67. package/dist/types/use-weaverse-next-studio.d.ts.map +1 -0
  68. package/dist/types/utils.d.ts +12 -0
  69. package/dist/types/utils.d.ts.map +1 -0
  70. package/package.json +12 -8
  71. package/src/client.ts +102 -0
  72. package/src/hooks.ts +50 -0
  73. package/src/index.ts +153 -0
  74. package/src/item.ts +167 -0
  75. package/src/loader.ts +135 -0
  76. package/src/main.tsx +45 -0
  77. package/src/provider.tsx +225 -0
  78. package/src/registry.ts +63 -0
  79. package/src/renderer.tsx +100 -0
  80. package/src/request-info.ts +124 -0
  81. package/src/revalidate-item.ts +211 -0
  82. package/src/root-provider.tsx +182 -0
  83. package/src/runtime.ts +555 -0
  84. package/src/seo.ts +157 -0
  85. package/src/server/configs.ts +178 -0
  86. package/src/server/normalize-page-url.ts +73 -0
  87. package/src/server/revalidate-handler.ts +357 -0
  88. package/src/server/server-client.ts +728 -0
  89. package/src/server.ts +67 -0
  90. package/src/studio-bridge.tsx +82 -0
  91. package/src/studio-connect.tsx +88 -0
  92. package/src/studio-router.ts +85 -0
  93. package/src/studio-script-src.ts +128 -0
  94. package/src/theme-settings-store.ts +47 -0
  95. package/src/translation-context.tsx +299 -0
  96. package/src/translation-store.ts +69 -0
  97. package/src/types.ts +753 -0
  98. package/src/use-weaverse-next-studio.tsx +106 -0
  99. package/src/utils.ts +37 -0
  100. package/dist/chunk-6PMZ77RA.mjs.map +0 -1
  101. package/dist/index.d.mts +0 -517
  102. package/dist/index.d.ts +0 -517
  103. package/dist/seo-CpN6tC36.d.mts +0 -477
  104. package/dist/seo-CpN6tC36.d.ts +0 -477
  105. package/dist/server.d.mts +0 -99
  106. package/dist/server.d.ts +0 -99
package/dist/server.mjs CHANGED
@@ -1,5 +1,6 @@
1
- import { generateDataFromSchema, buildWeaverseNextRequestInfo, runWeaverseComponentLoaders } from './chunk-6PMZ77RA.mjs';
2
- export { formatWeaverseNextSeoMetadata, getWeaverseNextSeoMetadata } from './chunk-6PMZ77RA.mjs';
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';
3
4
 
4
5
  // src/server/configs.ts
5
6
  var DEFAULT_WEAVERSE_HOST = "https://studio.weaverse.io";
@@ -72,7 +73,6 @@ function getWeaverseNextConfigs(context, options = {}) {
72
73
  envProjectId: readEnv(env, "WEAVERSE_PROJECT_ID") || "",
73
74
  weaverseHost,
74
75
  weaverseApiBase,
75
- weaverseApiKey: lastParam(searchParams, "weaverseApiKey") || readEnv(env, "WEAVERSE_API_KEY") || "",
76
76
  weaverseVersion: lastParam(searchParams, "weaverseVersion") || options.weaverseVersion || "",
77
77
  isDesignMode,
78
78
  isPreviewMode,
@@ -110,14 +110,19 @@ function normalizeNextPageUrl(url) {
110
110
  }
111
111
  function resolveRequestUrl(context) {
112
112
  if (context?.url) {
113
- return typeof context.url === "string" ? context.url : context.url.toString();
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();
114
121
  }
115
- let pathname = context?.pathname || "/";
122
+ let pathname = withPathPrefix(context?.pathname || "/", context?.i18n);
116
123
  let search = context?.searchParams ? new URLSearchParams(context.searchParams).toString() : "";
117
124
  return `http://localhost${pathname}${search ? `?${search}` : ""}`;
118
125
  }
119
-
120
- // src/server/revalidate-handler.ts
121
126
  var NO_STORE_HEADERS = {
122
127
  "Content-Type": "application/json",
123
128
  "Cache-Control": "no-store"
@@ -127,6 +132,119 @@ var STATUS_BAD_REQUEST = 400;
127
132
  var STATUS_NOT_FOUND = 404;
128
133
  var STATUS_UNPROCESSABLE = 422;
129
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
+ }
130
248
  function json(body, status) {
131
249
  return new Response(JSON.stringify(body), {
132
250
  status,
@@ -160,9 +278,18 @@ function createWeaverseNextRevalidateHandler(config) {
160
278
  if (!draftItem) {
161
279
  return json({ error: "invalid-payload" }, STATUS_BAD_REQUEST);
162
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
+ }
163
290
  let client;
164
291
  try {
165
- client = await config.getClient(request);
292
+ client = await config.getClient(request, requestContext);
166
293
  } catch (error) {
167
294
  console.error("\u274C Revalidate handler getClient failed.", error);
168
295
  return json({ error: "client-init-failed" }, STATUS_SERVER_ERROR);
@@ -595,12 +722,58 @@ var NextServerClient = class {
595
722
  return null;
596
723
  }
597
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
+ }
598
773
  loadThemeSettings = async (optionsInput = {}) => {
599
774
  let options = optionsInput;
600
775
  let themeSchema = asThemeSchema(this.themeSchema);
601
- let defaultThemeSettings = generateDataFromSchema(
602
- this.themeSchema
603
- );
776
+ let defaultThemeSettings = generateDataFromSchema(this.themeSchema);
604
777
  let staticContent = themeSchema?.i18n?.staticContent;
605
778
  try {
606
779
  let projectId = await this.resolveProjectId();
@@ -609,16 +782,16 @@ var NextServerClient = class {
609
782
  }
610
783
  let { isDesignMode } = this._baseConfigs;
611
784
  let url = `${this._baseConfigs.weaverseApiBase}/api/public/project_configs`;
612
- let result = await this.fetchWithCache(
613
- url,
614
- {
785
+ let [result, merchantOverrides] = await Promise.all([
786
+ this.fetchWithCache(url, {
615
787
  method: "POST",
616
788
  body: JSON.stringify({ projectId, isDesignMode }),
617
789
  headers: JSON_HEADERS,
618
790
  revalidate: options.revalidate,
619
791
  tags: options.tags
620
- }
621
- );
792
+ }),
793
+ this._fetchMerchantOverrides(projectId, options)
794
+ ]);
622
795
  if (typeof result !== "object" || result === null) {
623
796
  result = { theme: defaultThemeSettings };
624
797
  }
@@ -632,21 +805,25 @@ var NextServerClient = class {
632
805
  if (staticContent) {
633
806
  result.staticContent = staticContent;
634
807
  }
808
+ if (merchantOverrides) {
809
+ result.merchantOverrides = merchantOverrides;
810
+ }
635
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;
636
824
  result = {
637
825
  ...result,
638
- schema: themeSchema ? {
639
- ...themeSchema,
640
- settings: themeSchema.settings?.map((group) => ({
641
- ...group,
642
- inputs: group?.inputs?.map(
643
- (inputItem) => typeof inputItem?.condition === "function" ? {
644
- ...inputItem,
645
- condition: inputItem.condition.toString()
646
- } : inputItem
647
- )
648
- }))
649
- } : void 0,
826
+ schema: serializableSchema,
650
827
  publicEnv: this._baseConfigs.publicEnv
651
828
  };
652
829
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server/configs.ts","../src/server/normalize-page-url.ts","../src/server/revalidate-handler.ts","../src/server/server-client.ts"],"names":[],"mappings":";;;;AAKA,IAAM,qBAAA,GAAwB,4BAAA;AAC9B,IAAM,yBAAA,GAA4B,yBAAA;AAOlC,IAAM,sBAAA,GAAyB,CAAC,aAAA,EAAe,cAAc,CAAA;AAS7D,SAAS,oBAAoB,IAAA,EAAuB;AAClD,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,IAAI,IAAI,IAAI,CAAA;AAAA,EACvB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,MAAA,CAAO,aAAa,QAAA,EAAU;AAChC,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,EAAE,UAAS,GAAI,MAAA;AACnB,EAAA,OAAO,sBAAA,CAAuB,IAAA;AAAA,IAC5B,CAAC,WAAW,QAAA,KAAa,MAAA,IAAU,SAAS,QAAA,CAAS,CAAA,CAAA,EAAI,MAAM,CAAA,CAAE;AAAA,GACnE;AACF;AAEA,SAAS,MAAM,KAAA,EAAiC;AAC9C,EAAA,IAAI;AACF,IAAA,OAAO,OAAO,KAAA,KAAU,QAAA,GACpB,IAAI,GAAA,CAAI,KAAA,EAAO,kBAAkB,CAAA,GACjC,KAAA;AAAA,EACN,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAMO,SAAS,uBACd,OAAA,EACiB;AACjB,EAAA,IAAI,SAAS,YAAA,EAAc;AACzB,IAAA,OAAO,IAAI,eAAA,CAAgB,OAAA,CAAQ,YAAY,CAAA;AAAA,EACjD;AACA,EAAA,IAAI,SAAS,GAAA,EAAK;AAChB,IAAA,IAAI,GAAA,GAAM,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA;AAC3B,IAAA,IAAI,GAAA,EAAK;AACP,MAAA,OAAO,IAAI,eAAA,CAAgB,GAAA,CAAI,YAAY,CAAA;AAAA,IAC7C;AAAA,EACF;AACA,EAAA,OAAO,IAAI,eAAA,EAAgB;AAC7B;AAQA,SAAS,SAAA,CACP,cACA,GAAA,EACoB;AACpB,EAAA,IAAI,MAAA,GAAS,YAAA,CAAa,MAAA,CAAO,GAAG,CAAA;AACpC,EAAA,OAAO,MAAA,CAAO,MAAA,GAAS,MAAA,CAAO,EAAA,CAAG,EAAE,CAAA,GAAI,MAAA;AACzC;AAEA,SAAS,WAAW,KAAA,EAAoC;AACtD,EAAA,OAAO,KAAA,KAAU,MAAA;AACnB;AAEA,SAAS,OAAA,CACP,KACA,GAAA,EACoB;AACpB,EAAA,IAAI,UAAA,GAAa,MAAM,GAAG,CAAA;AAC1B,EAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,IAAA,OAAO,UAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,EAAK;AACjD,IAAA,OAAO,OAAA,CAAQ,IAAI,GAAG,CAAA;AAAA,EACxB;AACA,EAAA;AACF;AAiBO,SAAS,sBAAA,CACd,OAAA,EACA,OAAA,GAAiC,EAAC,EACT;AACzB,EAAA,IAAI,YAAA,GAAe,uBAAuB,OAAO,CAAA;AACjD,EAAA,IAAI,EAAE,KAAI,GAAI,OAAA;AAEd,EAAA,IAAI,SAAA,GAAY,SAAA,CAAU,YAAA,EAAc,cAAc,CAAA;AAKtD,EAAA,IAAI,cAAA,GACF,aAAa,mBAAA,CAAoB,SAAS,IAAI,IAAI,GAAA,CAAI,SAAS,CAAA,CAAE,MAAA,GAAS,EAAA;AAE5E,EAAA,IAAI,iBACF,OAAA,CAAQ,YAAA,IAAgB,OAAA,CAAQ,GAAA,EAAK,eAAe,CAAA,IAAK,EAAA;AAC3D,EAAA,IAAI,YAAA,GAAe,kBAAkB,cAAA,IAAkB,qBAAA;AAKvD,EAAA,IAAI,eAAA,GACF,cAAA,IACA,OAAA,CAAQ,eAAA,IACR,OAAA,CAAQ,GAAA,EAAK,0BAA0B,CAAA,KACtC,cAAA,IAAkB,cAAA,KAAmB,qBAAA,GAClC,cAAA,GACA,yBAAA,CAAA;AAEN,EAAA,IAAI,iBAAA,GACF,OAAA,EAAS,iBAAA,IAAqB,YAAA,CAAa,IAAI,cAAc,CAAA;AAC/D,EAAA,IAAI,eACF,OAAA,EAAS,YAAA,IAAgB,WAAW,SAAA,CAAU,YAAA,EAAc,cAAc,CAAC,CAAA;AAC7E,EAAA,IAAI,gBACF,OAAA,EAAS,aAAA,IACT,WAAW,SAAA,CAAU,YAAA,EAAc,eAAe,CAAC,CAAA;AAErD,EAAA,OAAO;AAAA,IACL,cAAA,EAAgB,SAAA,CAAU,YAAA,EAAc,mBAAmB,CAAA,IAAK,EAAA;AAAA,IAChE,YAAA,EAAc,OAAA,CAAQ,GAAA,EAAK,qBAAqB,CAAA,IAAK,EAAA;AAAA,IACrD,YAAA;AAAA,IACA,eAAA;AAAA,IACA,cAAA,EACE,UAAU,YAAA,EAAc,gBAAgB,KACxC,OAAA,CAAQ,GAAA,EAAK,kBAAkB,CAAA,IAC/B,EAAA;AAAA,IACF,iBACE,SAAA,CAAU,YAAA,EAAc,iBAAiB,CAAA,IACzC,QAAQ,eAAA,IACR,EAAA;AAAA,IACF,YAAA;AAAA,IACA,aAAA;AAAA,IACA,iBAAA;AAAA,IACA,aACE,OAAA,EAAS,WAAA,IAAe,SAAA,CAAU,YAAA,EAAc,aAAa,CAAA,IAAK,EAAA;AAAA,IACpE,SAAA,EAAW;AAAA,MACT,mBAAA,EAAqB,OAAA,CAAQ,GAAA,EAAK,qBAAqB,CAAA,IAAK,EAAA;AAAA,MAC5D,2BAAA,EACE,OAAA,CAAQ,GAAA,EAAK,6BAA6B,CAAA,IAAK;AAAA;AACnD,GACF;AACF;;;ACvKA,IAAM,aAAA,GACJ,6DAAA;AACF,IAAM,WAAA,GAAc,OAAA;AAYb,SAAS,qBAAqB,GAAA,EAAqB;AACxD,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,IAAI,IAAI,GAAG,CAAA;AAAA,EACtB,CAAA,CAAA,MAAQ;AACN,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,IAAI,GAAA,CAAI,GAAA,EAAK,kBAAkB,CAAA;AAAA,IAC1C,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,GAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,IAAI,IAAA,GAAO,CAAC,GAAG,MAAA,CAAO,YAAY,CAAA,CAAE,MAAA,CAAO,CAAC,CAAC,GAAG,CAAA,KAAM,aAAA,CAAc,IAAA,CAAK,GAAG,CAAC,CAAA;AAC7E,EAAA,IAAA,CAAK,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA,KAAM,CAAA,CAAE,aAAA,CAAc,CAAC,CAAC,CAAA;AAC1C,EAAA,IAAI,MAAA,GAAS,IAAI,eAAA,CAAgB,IAAI,EAAE,QAAA,EAAS;AAEhD,EAAA,IAAI,EAAE,UAAS,GAAI,MAAA;AACnB,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,WAAW,CAAA,EAAG;AAClC,IAAA,QAAA,GAAW,QAAA,CAAS,KAAA,CAAM,CAAA,EAAG,CAAC,YAAY,MAAM,CAAA;AAAA,EAClD;AACA,EAAA,OAAO,CAAA,EAAG,MAAA,CAAO,MAAM,CAAA,EAAG,QAAQ,GAAG,MAAA,GAAS,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA,GAAK,EAAE,CAAA,CAAA;AACjE;AAOO,SAAS,kBACd,OAAA,EACQ;AACR,EAAA,IAAI,SAAS,GAAA,EAAK;AAChB,IAAA,OAAO,OAAO,QAAQ,GAAA,KAAQ,QAAA,GAC1B,QAAQ,GAAA,GACR,OAAA,CAAQ,IAAI,QAAA,EAAS;AAAA,EAC3B;AACA,EAAA,IAAI,QAAA,GAAW,SAAS,QAAA,IAAY,GAAA;AACpC,EAAA,IAAI,MAAA,GAAS,SAAS,YAAA,GAClB,IAAI,gBAAgB,OAAA,CAAQ,YAAY,CAAA,CAAE,QAAA,EAAS,GACnD,EAAA;AACJ,EAAA,OAAO,mBAAmB,QAAQ,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,MAAM,KAAK,EAAE,CAAA,CAAA;AACjE;;;AC1DA,IAAM,gBAAA,GAAmB;AAAA,EACvB,cAAA,EAAgB,kBAAA;AAAA,EAChB,eAAA,EAAiB;AACnB,CAAA;AAEA,IAAM,SAAA,GAAY,GAAA;AAClB,IAAM,kBAAA,GAAqB,GAAA;AAC3B,IAAM,gBAAA,GAAmB,GAAA;AACzB,IAAM,oBAAA,GAAuB,GAAA;AAC7B,IAAM,mBAAA,GAAsB,GAAA;AAiB5B,SAAS,IAAA,CAAK,MAA+B,MAAA,EAAgB;AAC3D,EAAA,OAAO,IAAI,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,EAAG;AAAA,IACxC,MAAA;AAAA,IACA,OAAA,EAAS;AAAA,GACV,CAAA;AACH;AAEA,SAAS,eAAe,OAAA,EAAoD;AAC1E,EAAA,IAAI,OAAO,OAAA,KAAY,QAAA,IAAY,OAAA,KAAY,IAAA,EAAM;AACnD,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,YAAa,OAAA,CAAoC,SAAA;AACrD,EAAA,IAAI,OAAO,SAAA,KAAc,QAAA,IAAY,SAAA,KAAc,IAAA,EAAM;AACvD,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,EAAE,EAAA,EAAI,IAAA,EAAK,GAAI,SAAA;AACnB,EAAA,IAAI,OAAO,OAAO,QAAA,IAAY,CAAC,MAAM,OAAO,IAAA,KAAS,QAAA,IAAY,CAAC,IAAA,EAAM;AACtE,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,SAAA;AACT;AA0BO,SAAS,oCACd,MAAA,EACmD;AACnD,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,OAAO,OAAA,KAAqB;AAChC,MAAA,IAAI,OAAA;AACJ,MAAA,IAAI;AACF,QAAA,OAAA,GAAU,MAAM,QAAQ,IAAA,EAAK;AAAA,MAC/B,CAAA,CAAA,MAAQ;AACN,QAAA,OAAO,IAAA,CAAK,EAAE,KAAA,EAAO,iBAAA,IAAqB,kBAAkB,CAAA;AAAA,MAC9D;AAEA,MAAA,IAAI,SAAA,GAAY,eAAe,OAAO,CAAA;AACtC,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,OAAO,IAAA,CAAK,EAAE,KAAA,EAAO,iBAAA,IAAqB,kBAAkB,CAAA;AAAA,MAC9D;AAEA,MAAA,IAAI,MAAA;AACJ,MAAA,IAAI;AACF,QAAA,MAAA,GAAS,MAAM,MAAA,CAAO,SAAA,CAAU,OAAO,CAAA;AAAA,MACzC,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,+CAA0C,KAAK,CAAA;AAC7D,QAAA,OAAO,IAAA,CAAK,EAAE,KAAA,EAAO,oBAAA,IAAwB,mBAAmB,CAAA;AAAA,MAClE;AAEA,MAAA,IAAI,SAAA,GAAY,OAAO,UAAA,CAAW,IAAA;AAAA,QAChC,CAAC,SAAA,KAAc,SAAA,EAAW,MAAA,EAAQ,SAAS,SAAA,CAAU;AAAA,OACvD;AACA,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,OAAO,IAAA,CAAK,EAAE,KAAA,EAAO,wBAAA,IAA4B,gBAAgB,CAAA;AAAA,MACnE;AACA,MAAA,IAAI,OAAO,SAAA,CAAU,MAAA,KAAW,UAAA,EAAY;AAC1C,QAAA,OAAO,IAAA,CAAK,EAAE,KAAA,EAAO,gBAAA,IAAoB,oBAAoB,CAAA;AAAA,MAC/D;AAEA,MAAA,IAAI;AAGF,QAAA,IAAI,UAAA,GAAa,MAAM,SAAA,CAAU,MAAA,CAAO;AAAA,UACtC,IAAA,EAAM;AAAA,YACJ,GAAG,sBAAA,CAAuB,SAAA,CAAU,MAAM,CAAA;AAAA,YAC1C,GAAG,SAAA,CAAU;AAAA,WACf;AAAA,UACA,QAAA,EAAU,MAAA;AAAA,UACV,SAAS,MAAA,CAAO,cAAA;AAAA,UAChB,UAAU,MAAA,CAAO;AAAA,SAClB,CAAA;AACD,QAAA,OAAO,KAAK,EAAE,UAAA,EAAY,UAAA,IAAc,IAAA,IAAQ,SAAS,CAAA;AAAA,MAC3D,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA;AAAA,UACN,yCAAA;AAAA,UACA,SAAA,CAAU,IAAA;AAAA,UACV,SAAA,CAAU,EAAA;AAAA,UACV;AAAA,SACF;AACA,QAAA,OAAO,IAAA,CAAK,EAAE,KAAA,EAAO,eAAA,IAAmB,mBAAmB,CAAA;AAAA,MAC7D;AAAA,IACF;AAAA,GACF;AACF;;;AC3GA,IAAM,wBAAA,GAA2B,GAAA;AACjC,IAAM,eAAA,GAAkB,EAAA;AACxB,IAAM,qBAAA,GAAwB,CAAA;AAC9B,IAAM,qBAAA,GAAwB,GAAA;AAE9B,IAAM,YAAA,GAAe;AAAA,EACnB,cAAA,EAAgB,kBAAA;AAAA,EAChB,MAAA,EAAQ,kBAAA;AAAA,EACR,iBAAA,EAAmB;AACrB,CAAA;AAgBA,SAAS,cAAc,MAAA,EAA+C;AACpE,EAAA,OAAO,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,GAC9B,MAAA,GACD,MAAA;AACN;AAEA,SAAS,YAAA,GAAuB;AAC9B,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,YAAA,IAAgB,MAAA,EAAQ;AAC3D,IAAA,OAAO,OAAO,UAAA,EAAW;AAAA,EAC3B;AACA,EAAA,OAAO,CAAA,GAAA,EAAM,KAAK,MAAA,EAAO,CAAE,SAAS,eAAe,CAAA,CAAE,KAAA,CAAM,qBAAqB,CAAC,CAAA,CAAA;AACnF;AAUA,SAAS,oCACP,KAAA,EACwC;AACxC,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,EAAU;AACvC,IAAA;AAAA,EACF;AACA,EAAA,IAAI,EAAE,SAAA,EAAW,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAQ,MAAK,GAAI,KAAA;AAIhD,EAAA,IACE,OAAO,cAAc,QAAA,IACrB,OAAO,SAAS,QAAA,IAChB,OAAO,WAAW,QAAA,EAClB;AACA,IAAA;AAAA,EACF;AACA,EAAA,IAAI,UAAA,GAAyC;AAAA,IAC3C,SAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA,EAAQ,OAAO,MAAA,KAAW,QAAA,GAAW,MAAA,GAAS;AAAA,GAChD;AACA,EAAA,IAAI,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU;AACpC,IAAA,UAAA,CAAW,IAAA,GAAO,IAAA;AAAA,EACpB;AACA,EAAA,OAAO,UAAA;AACT;AAOA,IAAM,mBAAN,MAA2D;AAAA,EACzD,UAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,IAAA,GAAsC,IAAA;AAAA,EACtC,cAAuC,EAAC;AAAA,EACxC,OAAA;AAAA,EAEiB,eAAA;AAAA,EACA,YAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,eAAA;AAAA,EACT,kBAAA;AAAA,EAER,YAAY,MAAA,EAAwC;AASlD,IAAA,IAAA,CAAK,aAAa,MAAA,CAAO,UAAA;AACzB,IAAA,IAAA,CAAK,WAAW,MAAA,CAAO,QAAA;AACvB,IAAA,IAAA,CAAK,iBAAiB,MAAA,CAAO,cAAA;AAC7B,IAAA,IAAA,CAAK,cAAc,MAAA,CAAO,WAAA;AAE1B,IAAA,IAAA,CAAK,aAAA,GAAgB;AAAA,MACnB,GAAG,sBAAA,CAAuB,MAAA,CAAO,WAAqC,CAAA;AAAA,MACtE,GAAG,MAAA,CAAO;AAAA,KACZ;AACA,IAAA,IAAA,CAAK,kBAAkB,MAAA,CAAO,SAAA;AAC9B,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA,CAAO,KAAA,IAAS,UAAA,CAAW,KAAA;AACzC,IAAA,IAAA,CAAK,SAAS,MAAA,CAAO,KAAA;AACrB,IAAA,IAAA,CAAK,eAAA,GAAkB,OAAO,cAAA,IAAkB,wBAAA;AAEhD,IAAA,IAAA,CAAK,YAAA,GAAe,sBAAA,CAAuB,MAAA,CAAO,cAAA,EAAgB;AAAA,MAChE,KAAK,MAAA,CAAO,GAAA;AAAA,MACZ,cAAc,MAAA,CAAO,YAAA;AAAA,MACrB,iBAAiB,MAAA,CAAO,eAAA;AAAA,MACxB,iBAAiB,MAAA,CAAO;AAAA,KACzB,CAAA;AAKD,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,mBAAA;AAAA,MAClB,IAAA,CAAK,YAAA,CAAa,cAAA,KACf,OAAO,IAAA,CAAK,eAAA,KAAoB,QAAA,GAC7B,IAAA,CAAK,eAAA,CAAgB,IAAA,EAAK,GAC1B,EAAA,CAAA,IACJ,KAAK,YAAA,CAAa;AAAA,KACtB;AAAA,EACF;AAAA,EAEA,IAAI,SAAA,GAAoB;AACtB,IAAA,OAAO,KAAK,OAAA,CAAQ,SAAA;AAAA,EACtB;AAAA;AAAA,EAGA,IAAI,UAAA,GAAiD;AACnD,IAAA,OAAO,KAAK,QAAA,EAAU,UAAA;AAAA,EACxB;AAAA,EAEQ,oBAAoB,SAAA,EAAwC;AAClE,IAAA,IAAI,OAAO,IAAA,CAAK,YAAA;AAChB,IAAA,OAAO;AAAA,MACL,SAAA;AAAA,MACA,cAAc,IAAA,CAAK,YAAA;AAAA,MACnB,iBAAiB,IAAA,CAAK,eAAA;AAAA,MACtB,uBAAuB,IAAA,CAAK,eAAA;AAAA,MAC5B,iBAAiB,IAAA,CAAK,eAAA;AAAA,MACtB,cAAc,IAAA,CAAK,YAAA;AAAA,MACnB,eAAe,IAAA,CAAK,aAAA;AAAA,MACpB,mBAAmB,IAAA,CAAK,iBAAA;AAAA,MACxB,aAAa,IAAA,CAAK,WAAA;AAAA,MAClB,WAAW,IAAA,CAAK;AAAA,KAClB;AAAA,EACF;AAAA,EAEA,mBAAmB,YAA6B;AAC9C,IAAA,IAAI,IAAA,CAAK,uBAAuB,MAAA,EAAW;AACzC,MAAA,OAAO,IAAA,CAAK,kBAAA;AAAA,IACd;AAGA,IAAA,IAAI,QAAA,GAAW,KAAK,YAAA,CAAa,cAAA;AACjC,IAAA,IAAI,CAAC,QAAA,IAAY,OAAO,IAAA,CAAK,oBAAoB,UAAA,EAAY;AAC3D,MAAA,IAAI;AACF,QAAA,IAAI,KAAA,GAAQ,MAAM,IAAA,CAAK,eAAA,CAAgB,KAAK,cAAc,CAAA;AAC1D,QAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,MAAK,EAAG;AAC7C,UAAA,QAAA,GAAW,MAAM,IAAA,EAAK;AAAA,QACxB;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN,oEAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAAA,IACF;AACA,IAAA,IAAI,CAAC,QAAA,IAAY,OAAO,IAAA,CAAK,oBAAoB,QAAA,EAAU;AACzD,MAAA,QAAA,GAAW,IAAA,CAAK,gBAAgB,IAAA,EAAK;AAAA,IACvC;AACA,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,QAAA,GAAW,KAAK,YAAA,CAAa,YAAA;AAAA,IAC/B;AAEA,IAAA,IAAA,CAAK,kBAAA,GAAqB,QAAA;AAC1B,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,mBAAA,CAAoB,QAAQ,CAAA;AAChD,IAAA,OAAO,QAAA;AAAA,EACT,CAAA;AAAA,EAEA,cAAA,GAAiB,OACf,GAAA,EACA,OAAA,GAAoC,EAAC,KACtB;AACf,IAAA,IAAI,EAAE,UAAA,EAAY,IAAA,EAAM,GAAG,MAAK,GAAI,OAAA;AACpC,IAAA,IAAI,WAAA,GAA+B,EAAE,GAAG,IAAA,EAAK;AAE7C,IAAA,IAAI,EAAE,YAAA,EAAc,iBAAA,EAAkB,GAAI,IAAA,CAAK,YAAA;AAC/C,IAAA,IAAI,gBAAgB,iBAAA,EAAmB;AAErC,MAAA,WAAA,CAAY,KAAA,GAAQ,UAAA;AAAA,IACtB,CAAA,MAAA,IAAW,WAAA,CAAY,KAAA,KAAU,MAAA,EAAW;AAC1C,MAAA,IAAI,mBAAA,GAAsB,UAAA,IAAc,IAAA,CAAK,MAAA,EAAQ,UAAA;AACrD,MAAA,IAAI,aAAA,GAAgB,IAAA,IAAQ,IAAA,CAAK,MAAA,EAAQ,IAAA;AACzC,MAAA,IAAI,mBAAA,KAAwB,MAAA,IAAa,aAAA,EAAe,MAAA,EAAQ;AAC9D,QAAA,WAAA,CAAY,IAAA,GAAO;AAAA,UACjB,GAAI,mBAAA,KAAwB,MAAA,GACxB,EAAC,GACD,EAAE,YAAY,mBAAA,EAAoB;AAAA,UACtC,GAAI,aAAA,EAAe,MAAA,GAAS,EAAE,IAAA,EAAM,aAAA,KAAkB;AAAC,SACzD;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,UAAA,GAAa,IAAI,eAAA,EAAgB;AACrC,IAAA,IAAI,YAAY,UAAA,CAAW,MAAM,WAAW,KAAA,EAAM,EAAG,KAAK,eAAe,CAAA;AACzE,IAAA,IAAI;AACF,MAAA,IAAI,QAAA,GAAW,MAAM,IAAA,CAAK,MAAA,CAAO,GAAA,EAAK;AAAA,QACpC,GAAG,WAAA;AAAA,QACH,MAAA,EAAQ,WAAA,CAAY,MAAA,IAAU,UAAA,CAAW;AAAA,OAC1C,CAAA;AACD,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,MAAM,IAAI,MAAM,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAAA,MACnE;AACA,MAAA,OAAQ,MAAM,SAAS,IAAA,EAAK;AAAA,IAC9B,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,SAAS,CAAA;AAAA,IACxB;AAAA,EACF,CAAA;AAAA,EAEQ,oBAAA,CACN,SAAA,EACA,OAAA,EACA,MAAA,EACA;AACA,IAAA,IAAI,MAAA,GAAS,IAAI,eAAA,EAAgB;AACjC,IAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,MAAA,MAAA,CAAO,GAAA,CAAI,QAAA,EAAU,OAAA,CAAQ,MAAM,CAAA;AAAA,IACrC;AACA,IAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,MAAA,MAAA,CAAO,GAAA,CAAI,OAAA,EAAS,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAC3C;AACA,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAA,CAAO,GAAA,CAAI,UAAU,MAAM,CAAA;AAAA,IAC7B;AACA,IAAA,IAAI,EAAA,GAAK,OAAO,QAAA,EAAS;AACzB,IAAA,OAAO,CAAA,EAAG,IAAA,CAAK,YAAA,CAAa,eAAe,CAAA,wBAAA,EAA2B,SAAS,CAAA,aAAA,EAC7E,EAAA,GAAK,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA,GAAK,EAClB,CAAA,CAAA;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,gBAAA,GAAmB,OACjB,OAAA,GAA+C,EAAC,KACL;AAC3C,IAAA,IAAI,SAAA,GAAY,MAAM,IAAA,CAAK,gBAAA,EAAiB;AAC5C,IAAA,IAAI,UAAyC,EAAC;AAC9C,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN;AAAA,OACF;AACA,MAAA,OAAO,OAAA;AAAA,IACT;AAEA,IAAA,IAAI,MAAA,GAAwB,IAAA;AAC5B,IAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,GAAO,qBAAA,EAAuB,QAAQ,CAAA,EAAG;AAC1D,MAAA,IAAI,GAAA,GAAM,IAAA,CAAK,oBAAA,CAAqB,SAAA,EAAW,SAAS,MAAM,CAAA;AAE9D,MAAA,IAAI;AACF,QAAA,IAAI,MAAA,GAAS,MAAM,IAAA,CAAK,cAAA,CAGrB,GAAA,EAAK;AAAA,UACN,YAAY,OAAA,CAAQ,UAAA;AAAA,UACpB,MAAM,OAAA,CAAQ;AAAA,SACf,CAAA;AACD,QAAA,OAAA,CAAQ,IAAA,CAAK,GAAI,MAAA,CAAO,IAAA,IAAQ,EAAG,CAAA;AACnC,QAAA,IAAI,CAAC,OAAO,UAAA,EAAY;AACtB,UAAA,OAAO,OAAA;AAAA,QACT;AACA,QAAA,MAAA,GAAS,MAAA,CAAO,UAAA;AAAA,MAClB,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACnE,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN,QAAQ,MAAA,KAAW,CAAA,GACf,gDAAgD,OAAO,CAAA,CAAA,GACvD,uDAAuD,OAAO,CAAA;AAAA,SACpE;AACA,QAAA,OAAO,OAAA;AAAA,MACT;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,KAAK,oDAAoD,CAAA;AACjE,IAAA,OAAO,OAAA;AAAA,EACT,CAAA;AAAA,EAEQ,sBAAsB,OAAA,EAAuC;AACnE,IAAA,IAAI,SAAS,YAAA,EAAa;AAC1B,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,iBAAiB,MAAM,CAAA,CAAA;AAAA,MAC3B,MAAA;AAAA,MACA,IAAA,EAAM,cAAA;AAAA,MACN,KAAA,EAAO;AAAA,QACL;AAAA,UACE,IAAA,EAAM,MAAA;AAAA,UACN,EAAA,EAAI,MAAA;AAAA,UACJ,MAAM,EAAE,uBAAA,EAAyB,EAAE,MAAA,EAAQ,SAAQ;AAAE;AACvD;AACF,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,kBAAA,CACN,IAAA,EACA,KAAA,EACA,QAAA,GAAoC,EAAC,EACjB;AACpB,IAAA,IAAI,SAAA,GAAY,KAAK,UAAA,CAAW,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,EAAQ,IAAA,KAAS,IAAI,CAAA;AACnE,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA;AAAA,IACF;AACA,IAAA,IAAI,EAAE,UAAU,GAAG,IAAA,KAAU,SAAA,CAAU,MAAA,EAAQ,WAAW,EAAC;AAI3D,IAAA,IAAI,WAA6B,EAAC;AAClC,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,KAAA,IAAS,SAAS,QAAA,EAAU;AAC1B,QAAA,IAAI,EAAE,IAAA,EAAM,SAAA,EAAW,UAAU,SAAA,EAAW,GAAG,WAAU,GAAI,KAAA;AAC7D,QAAA,IAAI,OAAA,GAAU,IAAA,CAAK,kBAAA,CAAmB,SAAA,EAAW,OAAO,SAAS,CAAA;AACjE,QAAA,IAAI,OAAA,EAAS;AACX,UAAA,QAAA,CAAS,IAAA,CAAK,EAAE,EAAA,EAAI,OAAA,EAAS,CAAA;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AACA,IAAA,IAAI,KAAK,YAAA,EAAa;AACtB,IAAA,KAAA,CAAM,IAAA,CAAK,EAAE,EAAA,EAAI,IAAA,EAAM,IAAA,EAAM,EAAE,GAAG,IAAA,EAAM,GAAG,QAAA,EAAS,EAAG,QAAA,EAAU,UAAU,CAAA;AAC3E,IAAA,OAAO,EAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,qBAAqB,SAAA,EAA2C;AACtE,IAAA,IAAI,EAAE,WAAA,EAAa,YAAA,EAAa,GAAI,IAAA,CAAK,YAAA;AACzC,IAAA,IAAI,QAAqC,EAAC;AAC1C,IAAA,IAAI,YAAY,WAAA,GACZ,IAAA,CAAK,kBAAA,CAAmB,WAAA,EAAa,KAAK,CAAA,GAC1C,MAAA;AAEJ,IAAA,IAAI,OAAA,GAAU;AAAA,MACZ,GAAG,IAAA,CAAK,mBAAA,CAAoB,SAAS,CAAA;AAAA,MACrC,aAAA,EAAe,IAAA;AAAA,MACf,YAAA;AAAA,MACA,WAAA,EAAa,4BAAA,CAA6B,IAAA,CAAK,cAAc;AAAA,KAC/D;AAEA,IAAA,OAAO;AAAA,MACL,OAAA,EAAS;AAAA,QACP,EAAA,EAAI,SAAA;AAAA,QACJ,cAAA,EAAgB,SAAA;AAAA,QAChB,IAAA,EAAM;AAAA,OACR;AAAA,MACA,OAAA;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,EAAA,EAAI,uBAAA;AAAA,QACJ,IAAA,EAAM,iBAAA;AAAA,QACN,MAAA,EAAQ,GAAA;AAAA,QACR,KAAA,EAAO;AAAA,UACL;AAAA,YACE,EAAA,EAAI,GAAA;AAAA,YACJ,IAAA,EAAM,MAAA;AAAA,YACN,MAAM,EAAC;AAAA,YACP,QAAA,EAAU,YAAY,CAAC,EAAE,IAAI,SAAA,EAAW,IAAI;AAAC,WAC/C;AAAA,UACA,GAAG;AAAA;AACL;AACF,KACF;AAAA,EACF;AAAA,EAEQ,kBAAkB,KAAA,EAAkC;AAC1D,IAAA,IAAI;AAAA,MACF,KAAA;AAAA,MACA,SAAA,EAAW,cAAA;AAAA,MACX,GAAG;AAAA,KACL,GAAI,KAAA;AACJ,IAAA,IAAI,SAAkC,EAAC;AACvC,IAAA,KAAA,IAAS,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,EAAG;AAC7C,MAAA,IAAI,UAAU,MAAA,EAAW;AACvB,QAAA,MAAA,CAAO,GAAG,CAAA,GAAI,KAAA;AAAA,MAChB;AAAA,IACF;AACA,IAAA,OAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,cAAA,EAAe;AAAA,EACzC;AAAA,EAEA,MAAc,0BAA0B,cAAA,EAAyB;AAC/D,IAAA,IAAI,kBAAA,GACD,OAAO,cAAA,KAAmB,QAAA,IAAY,eAAe,IAAA,EAAK,IAC1D,MAAM,IAAA,CAAK,gBAAA,EAAiB;AAC/B,IAAA,IAAI,kBAAA,EAAoB;AACtB,MAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,mBAAA,CAAoB,kBAAkB,CAAA;AAAA,IAC5D;AACA,IAAA,OAAO,kBAAA;AAAA,EACT;AAAA,EAEQ,iBAAA,CACN,SAAA,EACA,MAAA,EACA,KAAA,EACA;AACA,IAAA,IAAI,OAAO,IAAA,CAAK,cAAA,EAAgB,IAAA,IAAQ,IAAA,CAAK,UAAU,UAAA,EAAY,IAAA;AACnE,IAAA,IAAI,GAAA,GAAM,oBAAA,CAAqB,iBAAA,CAAkB,IAAA,CAAK,cAAc,CAAC,CAAA;AACrE,IAAA,IAAI,MAAA,GAAS,CAAA,EAAG,IAAA,CAAK,YAAA,CAAa,eAAe,CAAA,mBAAA,CAAA;AACjD,IAAA,IAAI,YAAY,IAAA,CAAK,cAAA,EAAgB,OAAA,EAAS,GAAA,CAAI,YAAY,CAAA,IAAK,EAAA;AACnE,IAAA,OAAO,IAAA,CAAK,eAAwC,MAAA,EAAQ;AAAA,MAC1D,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,SAAA;AAAA,QACA,GAAA;AAAA,QACA,IAAA;AAAA,QACA,MAAA;AAAA,QACA,YAAA,EAAc,KAAK,YAAA,CAAa;AAAA,OACjC,CAAA;AAAA,MACD,OAAA,EAAS,EAAE,GAAG,YAAA,EAAc,gBAAgB,SAAA,EAAU;AAAA,MACtD,GAAI,SAAS;AAAC,KACf,CAAA;AAAA,EACH;AAAA,EAEQ,mBAAmB,OAAA,EAAkC;AAC3D,IAAA,IAAI,OAAA,IAAW,OAAA,IAAW,OAAO,OAAA,CAAQ,UAAU,QAAA,EAAU;AAC3D,MAAA,MAAM,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA;AAAA,IAC/B;AAAA,EACF;AAAA,EAEQ,iBAAA,CACN,SACA,SAAA,EACwB;AACxB,IAAA,IAAA,CAAK,mBAAmB,OAAO,CAAA;AAC/B,IAAA,IAAI,OAAO,OAAA,CAAQ,IAAA;AACnB,IAAA,IAAI,UAAU,OAAA,CAAQ,OAAA;AACtB,IAAA,IAAI,cAAA,GAAiB,mCAAA;AAAA,MACnB,OAAA,CAAQ;AAAA,KACV;AAEA,IAAA,IAAA,KAAS,IAAA,CAAK,qBAAA;AAAA,MACZ;AAAA,KACF;AACA,IAAA,OAAA,KAAY;AAAA,MACV,EAAA,EAAI,SAAA;AAAA,MACJ,IAAA,EAAM,6BAAA;AAAA,MACN,cAAA,EAAgB;AAAA,KAClB;AACA,IAAA,IAAI,KAAA,CAAM,QAAQ,IAAA,CAAK,KAAK,KAAK,IAAA,CAAK,KAAA,CAAM,WAAW,CAAA,EAAG;AACxD,MAAA,IAAA,CAAK,MAAM,IAAA,CAAK;AAAA,QACd,IAAA,EAAM,MAAA;AAAA,QACN,EAAA,EAAI,IAAA,CAAK,MAAA,IAAU,YAAA,EAAa;AAAA,QAChC,MAAM;AAAC,OACR,CAAA;AAAA,IACH;AAEA,IAAA,OAAO;AAAA,MACL,IAAA;AAAA,MACA,OAAA;AAAA,MACA,cAAA;AAAA,MACA,OAAA,EAAS;AAAA,QACP,GAAG,IAAA,CAAK,mBAAA,CAAoB,SAAS,CAAA;AAAA,QACrC,WAAA,EAAa,4BAAA,CAA6B,IAAA,CAAK,cAAc;AAAA;AAC/D,KACF;AAAA,EACF;AAAA,EAEA,MAAc,YAAY,IAAA,EAA8B;AACtD,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAI,cAAc,MAAM,2BAAA,CAA4B,EAAE,MAAA,EAAQ,IAAA,EAAM,MAAM,CAAA;AAC1E,IAAA,IAAA,CAAK,OAAO,WAAA,IAAe,IAAA;AAC3B,IAAA,OAAO,IAAA,CAAK,IAAA;AAAA,EACd;AAAA,EAEA,QAAA,GAAW,OACT,KAAA,GAAmC,EAAC,KACO;AAC3C,IAAA,IAAI;AACF,MAAA,IAAI,EAAE,KAAA,EAAO,MAAA,EAAQ,gBAAe,GAAI,IAAA,CAAK,kBAAkB,KAAK,CAAA;AACpE,MAAA,IAAI,SAAA,GAAY,MAAM,IAAA,CAAK,yBAAA,CAA0B,cAAc,CAAA;AACnE,MAAA,IAAI,IAAA,CAAK,aAAa,aAAA,EAAe;AACnC,QAAA,IAAI,WAAA,GAAc,IAAA,CAAK,oBAAA,CAAqB,SAAA,IAAa,GAAG,CAAA;AAC5D,QAAA,IAAA,CAAK,IAAA,GAAO,WAAA;AACZ,QAAA,OAAO,WAAA;AAAA,MACT;AACA,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,MAAM,IAAI,MAAM,6BAA6B,CAAA;AAAA,MAC/C;AAEA,MAAA,IAAI,UAAU,MAAM,IAAA,CAAK,iBAAA,CAAkB,SAAA,EAAW,QAAQ,KAAK,CAAA;AACnE,MAAA,IAAI,IAAA,GAAO,IAAA,CAAK,iBAAA,CAAkB,OAAA,EAAS,SAAS,CAAA;AACpD,MAAA,OAAO,MAAM,IAAA,CAAK,WAAA,CAAY,IAAI,CAAA;AAAA,IACpC,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,MAAM,yBAAA,EAAsB;AAAA,QAClC,GAAA,EAAK,KAAK,cAAA,EAAgB,GAAA;AAAA,QAC1B,SAAA,EAAW,KAAA,CAAM,SAAA,IAAa,IAAA,CAAK,OAAA,CAAQ,SAAA;AAAA,QAC3C,SAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC/D,CAAA;AACD,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF,CAAA;AAAA,EAEA,iBAAA,GAAoB,OAGlB,YAAA,GAEiC,EAAC,KACa;AAC/C,IAAA,IAAI,OAAA,GAAU,YAAA;AACd,IAAA,IAAI,WAAA,GAAc,aAAA,CAAc,IAAA,CAAK,WAAW,CAAA;AAChD,IAAA,IAAI,oBAAA,GAAuB,sBAAA;AAAA,MACzB,IAAA,CAAK;AAAA,KACP;AACA,IAAA,IAAI,aAAA,GAAgB,aAAa,IAAA,EAAM,aAAA;AAEvC,IAAA,IAAI;AACF,MAAA,IAAI,SAAA,GAAY,MAAM,IAAA,CAAK,gBAAA,EAAiB;AAC5C,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,MAAM,IAAI,MAAM,6BAA6B,CAAA;AAAA,MAC/C;AAEA,MAAA,IAAI,EAAE,YAAA,EAAa,GAAI,IAAA,CAAK,YAAA;AAC5B,MAAA,IAAI,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,YAAA,CAAa,eAAe,CAAA,2BAAA,CAAA;AAC9C,MAAA,IAAI,MAAA,GAAS,MAAM,IAAA,CAAK,cAAA;AAAA,QACtB,GAAA;AAAA,QACA;AAAA,UACE,MAAA,EAAQ,MAAA;AAAA,UACR,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,SAAA,EAAW,cAAc,CAAA;AAAA,UAChD,OAAA,EAAS,YAAA;AAAA,UACT,YAAY,OAAA,CAAQ,UAAA;AAAA,UACpB,MAAM,OAAA,CAAQ;AAAA;AAChB,OACF;AAEA,MAAA,IAAI,OAAO,MAAA,KAAW,QAAA,IAAY,MAAA,KAAW,IAAA,EAAM;AACjD,QAAA,MAAA,GAAS,EAAE,OAAO,oBAAA,EAAqB;AAAA,MACzC;AAEA,MAAA,IAAI,WAAA,EAAa,QAAA,IAAY,WAAA,EAAa,SAAA,EAAW;AACnD,QAAA,IAAI,CAAC,MAAA,CAAO,KAAA,IAAS,OAAO,MAAA,CAAO,UAAU,QAAA,EAAU;AACrD,UAAA,MAAA,CAAO,KAAA,GAAQ,oBAAA;AAAA,QACjB,CAAA,MAAO;AACL,UAAA,MAAA,CAAO,QAAQ,EAAE,GAAG,oBAAA,EAAsB,GAAG,OAAO,KAAA,EAAM;AAAA,QAC5D;AAAA,MACF;AAEA,MAAA,IAAI,aAAA,EAAe;AACjB,QAAA,MAAA,CAAO,aAAA,GAAgB,aAAA;AAAA,MACzB;AAEA,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,MAAA,GAAS;AAAA,UACP,GAAG,MAAA;AAAA,UACH,QAAQ,WAAA,GACJ;AAAA,YACE,GAAG,WAAA;AAAA,YACH,QAAA,EAAU,WAAA,CAAY,QAAA,EAAU,GAAA,CAAI,CAAC,KAAA,MAAW;AAAA,cAC9C,GAAG,KAAA;AAAA,cACH,MAAA,EAAQ,OAAO,MAAA,EAAQ,GAAA;AAAA,gBAAI,CAAC,SAAA,KAC1B,OAAO,SAAA,EAAW,cAAc,UAAA,GAC5B;AAAA,kBACE,GAAG,SAAA;AAAA,kBACH,SAAA,EAAW,SAAA,CAAU,SAAA,CAAU,QAAA;AAAS,iBAC1C,GACA;AAAA;AACN,aACF,CAAE;AAAA,WACJ,GACA,KAAA,CAAA;AAAA,UACJ,SAAA,EAAW,KAAK,YAAA,CAAa;AAAA,SAC/B;AAAA,MACF;AAEA,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,eAAe,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACxE,MAAA,OAAA,CAAQ,KAAA,CAAM,iCAAiC,YAAY,CAAA;AAC3D,MAAA,OAAO;AAAA,QACL,KAAA,EAAO,oBAAA;AAAA,QACP,aAAA;AAAA,QACA,MAAA,EAAQ,YAAA;AAAA,QACR,WAAA,EAAa;AAAA,OACf;AAAA,IACF;AAAA,EACF,CAAA;AACF,CAAA;AAmBO,SAAS,+BACd,MAAA,EAC0B;AAC1B,EAAA,OAAO,IAAI,iBAAiB,MAAM,CAAA;AACpC","file":"server.mjs","sourcesContent":["import type {\n WeaverseNextBaseConfigs,\n WeaverseNextRequestContext,\n} from '../types'\n\nconst DEFAULT_WEAVERSE_HOST = 'https://studio.weaverse.io'\nconst DEFAULT_WEAVERSE_API_BASE = 'https://api.weaverse.io'\n\n/**\n * Weaverse-controlled apex domains the Studio bridge / data API may be served\n * from (matched on the host itself and any subdomain). Kept in sync with\n * Hydrogen's `isTrustedStudioHost`.\n */\nconst TRUSTED_STUDIO_DOMAINS = ['weaverse.io', 'weaverse.dev']\n\n/**\n * Whether `host` is an origin we trust to resolve page/theme data. The\n * `weaverseHost` query param is attacker-controllable, so a crafted\n * `?weaverseHost=` must be rejected before it can point server-side fetches at\n * an arbitrary origin (SSRF). Only `weaverse.io`/`weaverse.dev` and subdomains\n * over https are trusted.\n */\nfunction isTrustedStudioHost(host: string): boolean {\n let parsed: URL\n try {\n parsed = new URL(host)\n } catch {\n return false\n }\n if (parsed.protocol !== 'https:') {\n return false\n }\n let { hostname } = parsed\n return TRUSTED_STUDIO_DOMAINS.some(\n (domain) => hostname === domain || hostname.endsWith(`.${domain}`)\n )\n}\n\nfunction toUrl(value: string | URL): URL | null {\n try {\n return typeof value === 'string'\n ? new URL(value, 'http://localhost')\n : value\n } catch {\n return null\n }\n}\n\n/**\n * Extract the request search params from the explicit Next request context.\n * Prefers `searchParams`, falls back to parsing `url`.\n */\nexport function getContextSearchParams(\n context?: WeaverseNextRequestContext\n): URLSearchParams {\n if (context?.searchParams) {\n return new URLSearchParams(context.searchParams)\n }\n if (context?.url) {\n let url = toUrl(context.url)\n if (url) {\n return new URLSearchParams(url.searchParams)\n }\n }\n return new URLSearchParams()\n}\n\n/**\n * Last value of a (possibly duplicated) query key. Matches Hydrogen's\n * `getRequestQueries`, which assigns while iterating and so keeps the last\n * occurrence — Studio appends its own control params, so a stale earlier value\n * must not win.\n */\nfunction lastParam(\n searchParams: URLSearchParams,\n key: string\n): string | undefined {\n let values = searchParams.getAll(key)\n return values.length ? values.at(-1) : undefined\n}\n\nfunction coerceBool(value: string | undefined): boolean {\n return value === 'true'\n}\n\nfunction readEnv(\n env: Record<string, string | undefined> | undefined,\n key: string\n): string | undefined {\n let fromConfig = env?.[key]\n if (fromConfig !== undefined) {\n return fromConfig\n }\n if (typeof process !== 'undefined' && process.env) {\n return process.env[key]\n }\n return\n}\n\nexport interface ResolveConfigsOptions {\n env?: Record<string, string | undefined>\n weaverseApiBase?: string\n weaverseHost?: string\n weaverseVersion?: string\n}\n\n/**\n * Derive Weaverse configs from the request context and env, close to Hydrogen's\n * `getWeaverseConfigs`. Resolves the trusted host, public API base, design /\n * preview / revision flags, and public env — but never resolves the final\n * `projectId` (that priority chain, which may call an async resolver, lives in\n * the server client). Query/env projectId candidates are returned for the\n * client to combine with function/string inputs.\n */\nexport function getWeaverseNextConfigs(\n context?: WeaverseNextRequestContext,\n options: ResolveConfigsOptions = {}\n): WeaverseNextBaseConfigs {\n let searchParams = getContextSearchParams(context)\n let { env } = options\n\n let queryHost = lastParam(searchParams, 'weaverseHost')\n // A trusted query host is canonicalized to its origin before use, so a crafted\n // `?weaverseHost=https://studio.weaverse.io/evil?x=1` can only ever resolve to\n // `https://studio.weaverse.io` — never carrying an attacker path/query into the\n // server-side API base.\n let trustedUrlHost =\n queryHost && isTrustedStudioHost(queryHost) ? new URL(queryHost).origin : ''\n\n let configuredHost =\n options.weaverseHost || readEnv(env, 'WEAVERSE_HOST') || ''\n let weaverseHost = trustedUrlHost || configuredHost || DEFAULT_WEAVERSE_HOST\n\n // Public data reads default to the edge proxy, but an explicit custom host\n // (staging/self-hosted Weaverse) must stay the API base so those deployments\n // don't fetch page/config data from the production proxy.\n let weaverseApiBase =\n trustedUrlHost ||\n options.weaverseApiBase ||\n readEnv(env, 'WEAVERSE_PUBLIC_API_BASE') ||\n (configuredHost && configuredHost !== DEFAULT_WEAVERSE_HOST\n ? configuredHost\n : DEFAULT_WEAVERSE_API_BASE)\n\n let isRevisionPreview =\n context?.isRevisionPreview ?? searchParams.has('__revisionId')\n let isDesignMode =\n context?.isDesignMode ?? coerceBool(lastParam(searchParams, 'isDesignMode'))\n let isPreviewMode =\n context?.isPreviewMode ??\n coerceBool(lastParam(searchParams, 'isPreviewMode'))\n\n return {\n queryProjectId: lastParam(searchParams, 'weaverseProjectId') || '',\n envProjectId: readEnv(env, 'WEAVERSE_PROJECT_ID') || '',\n weaverseHost,\n weaverseApiBase,\n weaverseApiKey:\n lastParam(searchParams, 'weaverseApiKey') ||\n readEnv(env, 'WEAVERSE_API_KEY') ||\n '',\n weaverseVersion:\n lastParam(searchParams, 'weaverseVersion') ||\n options.weaverseVersion ||\n '',\n isDesignMode,\n isPreviewMode,\n isRevisionPreview,\n sectionType:\n context?.sectionType || lastParam(searchParams, 'sectionType') || '',\n publicEnv: {\n PUBLIC_STORE_DOMAIN: readEnv(env, 'PUBLIC_STORE_DOMAIN') || '',\n PUBLIC_STOREFRONT_API_TOKEN:\n readEnv(env, 'PUBLIC_STOREFRONT_API_TOKEN') || '',\n },\n }\n}\n","import type { WeaverseNextRequestContext } from '../types'\n\n// Query params that influence Weaverse page resolution on the Builder:\n// revision previews, design-mode flags, design-mode draft item overrides,\n// and `weaverse*` control params (host, version, project id). Everything\n// else — utm_*, fbclid, gclid, storefront filters — is irrelevant to which\n// page the Builder returns and would otherwise fragment any fetch cache keyed\n// on the request body. `weaverseDraftItem` is the current draft item param;\n// `__weaverseDraftItem` is kept as a legacy compatibility alias.\nconst KEPT_PARAM_RE =\n /^(?:__revisionId|__weaverseDraftItem|isDesignMode|weaverse)/\nconst DATA_SUFFIX = '.data'\n\n/**\n * Normalize the storefront URL sent in the Builder page API request body.\n *\n * The Builder reads only the pathname (locale/type/handle fallback) and the\n * Weaverse/Studio control params from this URL, so keep exactly those and drop\n * tracking params. Params are sorted for a stable, cache-friendly string.\n *\n * Ported from `@weaverse/hydrogen`'s `normalizePageUrl`, but tolerant of a\n * relative URL (Next route handlers may only know the pathname).\n */\nexport function normalizeNextPageUrl(url: string): string {\n let parsed: URL\n try {\n parsed = new URL(url)\n } catch {\n try {\n parsed = new URL(url, 'http://localhost')\n } catch {\n return url\n }\n }\n\n let kept = [...parsed.searchParams].filter(([key]) => KEPT_PARAM_RE.test(key))\n kept.sort(([a], [b]) => a.localeCompare(b))\n let search = new URLSearchParams(kept).toString()\n\n let { pathname } = parsed\n if (pathname.endsWith(DATA_SUFFIX)) {\n pathname = pathname.slice(0, -DATA_SUFFIX.length)\n }\n return `${parsed.origin}${pathname}${search ? `?${search}` : ''}`\n}\n\n/**\n * Build an absolute-ish request URL string from the explicit request context,\n * preferring `url`, then `pathname` + `searchParams`. Used as the input to\n * {@link normalizeNextPageUrl}.\n */\nexport function resolveRequestUrl(\n context?: WeaverseNextRequestContext\n): string {\n if (context?.url) {\n return typeof context.url === 'string'\n ? context.url\n : context.url.toString()\n }\n let pathname = context?.pathname || '/'\n let search = context?.searchParams\n ? new URLSearchParams(context.searchParams).toString()\n : ''\n return `http://localhost${pathname}${search ? `?${search}` : ''}`\n}\n","import type {\n WeaverseNextComponentData,\n WeaverseNextServerClient,\n} from '../types'\nimport { generateDataFromSchema } from '../utils'\n\nconst NO_STORE_HEADERS = {\n 'Content-Type': 'application/json',\n 'Cache-Control': 'no-store',\n} as const\n\nconst STATUS_OK = 200\nconst STATUS_BAD_REQUEST = 400\nconst STATUS_NOT_FOUND = 404\nconst STATUS_UNPROCESSABLE = 422\nconst STATUS_SERVER_ERROR = 500\n\nexport interface WeaverseNextRevalidateHandlerConfig {\n /**\n * Reuse the app's server-client factory so the loader runs with the same\n * component registry and commerce (storefront) context as page loads.\n */\n getClient: (\n request: Request\n ) => Promise<WeaverseNextServerClient> | WeaverseNextServerClient\n}\n\n/** POST body accepted by the revalidate route. */\nexport interface WeaverseNextRevalidateRequestBody {\n draftItem: WeaverseNextComponentData\n}\n\nfunction json(body: Record<string, unknown>, status: number) {\n return new Response(JSON.stringify(body), {\n status,\n headers: NO_STORE_HEADERS,\n })\n}\n\nfunction parseDraftItem(payload: unknown): WeaverseNextComponentData | null {\n if (typeof payload !== 'object' || payload === null) {\n return null\n }\n let draftItem = (payload as { draftItem?: unknown }).draftItem\n if (typeof draftItem !== 'object' || draftItem === null) {\n return null\n }\n let { id, type } = draftItem as { id?: unknown; type?: unknown }\n if (typeof id !== 'string' || !id || typeof type !== 'string' || !type) {\n return null\n }\n return draftItem as WeaverseNextComponentData\n}\n\n/**\n * Create the Studio per-item revalidation route handler.\n *\n * Studio design-mode edits to loader-backed inputs (e.g. resource pickers) need\n * fresh server loader data for a single item. Re-running it through\n * `router.refresh()` re-applies the whole RSC tree — and the draft-item query\n * rewrite changes the App Router page segment key, remounting the page and\n * resetting scroll. This handler runs just the edited component's `loader`\n * with the unsaved draft settings and returns the payload for an in-place\n * client update (see the `2026-07-02--next-item-revalidation` spec).\n *\n * Security: only registered component types are executable, the handler never\n * persists anything, and responses are `no-store`. Exposure is equivalent to\n * the existing `weaverseDraftItem` URL param, which already lets any visitor\n * run design-mode loaders with arbitrary draft settings.\n *\n * @example\n * ```ts\n * // app/api/weaverse/revalidate/route.ts\n * export const { POST } = createWeaverseNextRevalidateHandler({\n * getClient: () => getWeaverseServerClient(Promise.resolve({})),\n * })\n * ```\n */\nexport function createWeaverseNextRevalidateHandler(\n config: WeaverseNextRevalidateHandlerConfig\n): { POST: (request: Request) => Promise<Response> } {\n return {\n POST: async (request: Request) => {\n let payload: unknown\n try {\n payload = await request.json()\n } catch {\n return json({ error: 'invalid-payload' }, STATUS_BAD_REQUEST)\n }\n\n let draftItem = parseDraftItem(payload)\n if (!draftItem) {\n return json({ error: 'invalid-payload' }, STATUS_BAD_REQUEST)\n }\n\n let client: WeaverseNextServerClient\n try {\n client = await config.getClient(request)\n } catch (error) {\n console.error('❌ Revalidate handler getClient failed.', error)\n return json({ error: 'client-init-failed' }, STATUS_SERVER_ERROR)\n }\n\n let component = client.components.find(\n (candidate) => candidate?.schema?.type === draftItem.type\n )\n if (!component) {\n return json({ error: 'unknown-component-type' }, STATUS_NOT_FOUND)\n }\n if (typeof component.loader !== 'function') {\n return json({ error: 'missing-loader' }, STATUS_UNPROCESSABLE)\n }\n\n try {\n // Same args shape as `runWeaverseComponentLoaders`, so component\n // loaders behave identically between page load and revalidation.\n let loaderData = await component.loader({\n data: {\n ...generateDataFromSchema(component.schema),\n ...draftItem.data,\n },\n weaverse: client,\n context: client.requestContext,\n commerce: client.commerce,\n })\n return json({ loaderData: loaderData ?? null }, STATUS_OK)\n } catch (error) {\n console.error(\n '❌ Item loader revalidation failed.',\n draftItem.type,\n draftItem.id,\n error\n )\n return json({ error: 'loader-failed' }, STATUS_SERVER_ERROR)\n }\n },\n }\n}\n","import type { SchemaType } from '@weaverse/schema'\nimport { runWeaverseComponentLoaders } from '../loader'\nimport { buildWeaverseNextRequestInfo } from '../request-info'\nimport type {\n WeaverseNextBaseConfigs,\n WeaverseNextCacheConfig,\n WeaverseNextCommerceContext,\n WeaverseNextComponent,\n WeaverseNextComponentData,\n WeaverseNextConfigs,\n WeaverseNextCustomPageEntry,\n WeaverseNextFetchCustomPagesOptions,\n WeaverseNextFetchOptions,\n WeaverseNextLoaderData,\n WeaverseNextLoadPageInput,\n WeaverseNextPageAssignment,\n WeaverseNextPageData,\n WeaverseNextProjectId,\n WeaverseNextRequestContext,\n WeaverseNextServerClient,\n WeaverseNextServerClientConfig,\n WeaverseNextServerLoadPageInput,\n WeaverseNextStorefront,\n WeaverseNextThemeSettingsOptions,\n WeaverseNextThemeSettingsResponse,\n} from '../types'\nimport { generateDataFromSchema } from '../utils'\nimport { getWeaverseNextConfigs } from './configs'\nimport { normalizeNextPageUrl, resolveRequestUrl } from './normalize-page-url'\n\nconst DEFAULT_FETCH_TIMEOUT_MS = 10_000\nconst RANDOM_ID_RADIX = 36\nconst RANDOM_ID_SLICE_START = 2\nconst MAX_CUSTOM_PAGE_PAGES = 100\n\nconst JSON_HEADERS = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'Accept-Encoding': 'gzip, deflate, br',\n} as const\n\n/** Next's `fetch` reads `next: { revalidate, tags }` off the request init. */\ntype NextRequestInit = RequestInit & {\n next?: { revalidate?: number | false; tags?: string[] }\n}\n\ninterface LooseThemeSchema {\n i18n?: { staticContent?: Record<string, unknown> }\n inspector?: unknown[]\n settings?: {\n inputs?: { condition?: unknown }[]\n [key: string]: unknown\n }[]\n}\n\nfunction asThemeSchema(schema: unknown): LooseThemeSchema | undefined {\n return schema && typeof schema === 'object'\n ? (schema as LooseThemeSchema)\n : undefined\n}\n\nfunction generateUuid(): string {\n if (typeof crypto !== 'undefined' && 'randomUUID' in crypto) {\n return crypto.randomUUID()\n }\n return `id-${Math.random().toString(RANDOM_ID_RADIX).slice(RANDOM_ID_SLICE_START)}`\n}\n\n/**\n * Normalize the raw `pageAssignment` from `/api/public/project` into a\n * save-compatible {@link WeaverseNextPageAssignment} so the Builder Studio save\n * pipeline receives the same shape it gets from Hydrogen. Returns `undefined`\n * for a missing or malformed assignment (rather than fabricating one), requires\n * string `projectId`/`type`/`handle`, coerces a nullish `locale` to `''`, and\n * preserves an object `meta` untouched.\n */\nfunction normalizeWeaverseNextPageAssignment(\n input: unknown\n): WeaverseNextPageAssignment | undefined {\n if (!input || typeof input !== 'object') {\n return\n }\n let { projectId, type, handle, locale, meta } = input as Record<\n string,\n unknown\n >\n if (\n typeof projectId !== 'string' ||\n typeof type !== 'string' ||\n typeof handle !== 'string'\n ) {\n return\n }\n let normalized: WeaverseNextPageAssignment = {\n projectId,\n type,\n handle,\n locale: typeof locale === 'string' ? locale : '',\n }\n if (meta && typeof meta === 'object') {\n normalized.meta = meta as WeaverseNextPageAssignment['meta']\n }\n return normalized\n}\n\n/**\n * Server-side Weaverse client for Next.js. Performs the real Weaverse public\n * API fetch (page + theme settings) instead of delegating to injected fetchers,\n * closing the gap with Hydrogen's `context.weaverse.loadPage(...)`.\n */\nclass NextServerClient implements WeaverseNextServerClient {\n components: WeaverseNextComponent[]\n commerce?: WeaverseNextCommerceContext\n requestContext?: WeaverseNextRequestContext\n themeSchema?: unknown\n themeSettings: Record<string, unknown>\n data: WeaverseNextLoaderData | null = null\n dataContext: Record<string, unknown> = {}\n configs: WeaverseNextConfigs\n\n private readonly _projectIdInput?: WeaverseNextProjectId\n private readonly _baseConfigs: WeaverseNextBaseConfigs\n private readonly _fetch: typeof fetch\n private readonly _cache?: WeaverseNextServerClientConfig['cache']\n private readonly _fetchTimeoutMs: number\n private _resolvedProjectId?: string\n\n constructor(config: WeaverseNextServerClientConfig) {\n // Server client keeps the component definitions for server-side loaders\n // (`runWeaverseComponentLoaders`) and preview-data generation, but it\n // intentionally does NOT call `registerWeaverseNextComponents`. Registering\n // pulls in `../registry` → `@weaverse/react`, which evaluates\n // `React.createContext()` at module load — invalid in the RSC/server graph\n // and the cause of `(0 , x.createContext) is not a function`. The client\n // wrapper/renderer (root `@weaverse/next` client entry) registers the real\n // render components instead, keeping `@weaverse/next/server` React-free.\n this.components = config.components\n this.commerce = config.commerce\n this.requestContext = config.requestContext\n this.themeSchema = config.themeSchema\n // Seed schema defaults before merchant overrides, mirroring the root client.\n this.themeSettings = {\n ...generateDataFromSchema(config.themeSchema as SchemaType | undefined),\n ...config.themeSettings,\n }\n this._projectIdInput = config.projectId\n this._fetch = config.fetch ?? globalThis.fetch\n this._cache = config.cache\n this._fetchTimeoutMs = config.fetchTimeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS\n\n this._baseConfigs = getWeaverseNextConfigs(config.requestContext, {\n env: config.env,\n weaverseHost: config.weaverseHost,\n weaverseApiBase: config.weaverseApiBase,\n weaverseVersion: config.weaverseVersion,\n })\n\n // Synchronous best-effort projectId (query → string → env). A function\n // resolver is awaited lazily in `resolveProjectId`, so `projectId` reflects\n // its result after the first `loadPage`/`loadThemeSettings`/`resolveProjectId`.\n this.configs = this._buildPublicConfigs(\n this._baseConfigs.queryProjectId ||\n (typeof this._projectIdInput === 'string'\n ? this._projectIdInput.trim()\n : '') ||\n this._baseConfigs.envProjectId\n )\n }\n\n get projectId(): string {\n return this.configs.projectId\n }\n\n /** Compatibility alias so loaders can call `weaverse.storefront.query(...)`. */\n get storefront(): WeaverseNextStorefront | undefined {\n return this.commerce?.storefront\n }\n\n private _buildPublicConfigs(projectId: string): WeaverseNextConfigs {\n let base = this._baseConfigs\n return {\n projectId,\n weaverseHost: base.weaverseHost,\n weaverseApiBase: base.weaverseApiBase,\n weaversePublicApiBase: base.weaverseApiBase,\n weaverseVersion: base.weaverseVersion,\n isDesignMode: base.isDesignMode,\n isPreviewMode: base.isPreviewMode,\n isRevisionPreview: base.isRevisionPreview,\n sectionType: base.sectionType,\n publicEnv: base.publicEnv,\n }\n }\n\n resolveProjectId = async (): Promise<string> => {\n if (this._resolvedProjectId !== undefined) {\n return this._resolvedProjectId\n }\n\n // Priority: query param → function → string → env (matches Hydrogen).\n let resolved = this._baseConfigs.queryProjectId\n if (!resolved && typeof this._projectIdInput === 'function') {\n try {\n let value = await this._projectIdInput(this.requestContext)\n if (typeof value === 'string' && value.trim()) {\n resolved = value.trim()\n }\n } catch (error) {\n console.warn(\n '[WeaverseNextServerClient] projectId resolver threw, falling back.',\n error\n )\n }\n }\n if (!resolved && typeof this._projectIdInput === 'string') {\n resolved = this._projectIdInput.trim()\n }\n if (!resolved) {\n resolved = this._baseConfigs.envProjectId\n }\n\n this._resolvedProjectId = resolved\n this.configs = this._buildPublicConfigs(resolved)\n return resolved\n }\n\n fetchWithCache = async <T = unknown>(\n url: string,\n options: WeaverseNextFetchOptions = {}\n ): Promise<T> => {\n let { revalidate, tags, ...init } = options\n let requestInit: NextRequestInit = { ...init }\n\n let { isDesignMode, isRevisionPreview } = this._baseConfigs\n if (isDesignMode || isRevisionPreview) {\n // Design / revision data must never be served stale.\n requestInit.cache = 'no-store'\n } else if (requestInit.cache === undefined) {\n let effectiveRevalidate = revalidate ?? this._cache?.revalidate\n let effectiveTags = tags ?? this._cache?.tags\n if (effectiveRevalidate !== undefined || effectiveTags?.length) {\n requestInit.next = {\n ...(effectiveRevalidate === undefined\n ? {}\n : { revalidate: effectiveRevalidate }),\n ...(effectiveTags?.length ? { tags: effectiveTags } : {}),\n }\n }\n }\n\n let controller = new AbortController()\n let timeoutId = setTimeout(() => controller.abort(), this._fetchTimeoutMs)\n try {\n let response = await this._fetch(url, {\n ...requestInit,\n signal: requestInit.signal ?? controller.signal,\n })\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n return (await response.json()) as T\n } finally {\n clearTimeout(timeoutId)\n }\n }\n\n private _buildCustomPagesUrl(\n projectId: string,\n options: WeaverseNextFetchCustomPagesOptions,\n cursor: string | null\n ) {\n let params = new URLSearchParams()\n if (options.locale) {\n params.set('locale', options.locale)\n }\n if (options.limit) {\n params.set('limit', String(options.limit))\n }\n if (cursor) {\n params.set('cursor', cursor)\n }\n let qs = params.toString()\n return `${this._baseConfigs.weaverseApiBase}/api/public/v1/projects/${projectId}/custom-pages${\n qs ? `?${qs}` : ''\n }`\n }\n\n /**\n * Fetch all published custom pages for sitemap generation. Mirrors Hydrogen's\n * helper but uses Next's fetch cache knobs (`revalidate` / `tags`). It returns\n * accumulated results on partial pagination failure so a single API hiccup\n * does not break sitemap generation entirely.\n */\n fetchCustomPages = async (\n options: WeaverseNextFetchCustomPagesOptions = {}\n ): Promise<WeaverseNextCustomPageEntry[]> => {\n let projectId = await this.resolveProjectId()\n let entries: WeaverseNextCustomPageEntry[] = []\n if (!projectId) {\n console.warn(\n '[WeaverseNext] Failed to fetch custom pages: missing projectId'\n )\n return entries\n }\n\n let cursor: string | null = null\n for (let page = 0; page < MAX_CUSTOM_PAGE_PAGES; page += 1) {\n let url = this._buildCustomPagesUrl(projectId, options, cursor)\n\n try {\n let result = await this.fetchWithCache<{\n data?: WeaverseNextCustomPageEntry[]\n nextCursor?: string | null\n }>(url, {\n revalidate: options.revalidate,\n tags: options.tags,\n })\n entries.push(...(result.data ?? []))\n if (!result.nextCursor) {\n return entries\n }\n cursor = result.nextCursor\n } catch (error) {\n let message = error instanceof Error ? error.message : String(error)\n console.warn(\n entries.length === 0\n ? `[WeaverseNext] Failed to fetch custom pages: ${message}`\n : `[WeaverseNext] Custom pages pagination interrupted: ${message}`\n )\n return entries\n }\n }\n\n console.warn('[WeaverseNext] Custom pages pagination cap reached')\n return entries\n }\n\n private _generateFallbackPage(message: string): WeaverseNextPageData {\n let rootId = generateUuid()\n return {\n id: `fallback_page_${rootId}`,\n rootId,\n name: 'Default Page',\n items: [\n {\n type: 'main',\n id: rootId,\n data: { dangerouslySetInnerHTML: { __html: message } },\n },\n ],\n }\n }\n\n /**\n * Recursively materialize a section preset (and its preset children) into a\n * flat list of page items, returning the new item id. Ported from Hydrogen's\n * `recursivelyAddDataItem`. Returns `undefined` when the type isn't registered.\n */\n private _buildPreviewItems(\n type: string,\n items: WeaverseNextComponentData[],\n initData: Record<string, unknown> = {}\n ): string | undefined {\n let component = this.components.find((c) => c.schema?.type === type)\n if (!component) {\n return\n }\n let { children, ...data } = (component.schema?.presets ?? {}) as {\n children?: { type: string; [key: string]: unknown }[]\n [key: string]: unknown\n }\n let childIds: { id: string }[] = []\n if (children) {\n for (let child of children) {\n let { type: childType, children: _children, ...childData } = child\n let childId = this._buildPreviewItems(childType, items, childData)\n if (childId) {\n childIds.push({ id: childId })\n }\n }\n }\n let id = generateUuid()\n items.push({ id, type, data: { ...data, ...initData }, children: childIds })\n return id\n }\n\n /**\n * Synthetic loader data for Studio \"section preview\" mode. Mirrors Hydrogen's\n * `getPreviewData`: it builds a single-section page from the requested\n * `sectionType`'s presets without hitting `/api/public/project`, so preview\n * works even without a resolved `projectId`.\n */\n private _generatePreviewData(projectId: string): WeaverseNextLoaderData {\n let { sectionType, weaverseHost } = this._baseConfigs\n let items: WeaverseNextComponentData[] = []\n let sectionId = sectionType\n ? this._buildPreviewItems(sectionType, items)\n : undefined\n\n let configs = {\n ...this._buildPublicConfigs(projectId),\n isPreviewMode: true,\n weaverseHost,\n requestInfo: buildWeaverseNextRequestInfo(this.requestContext),\n }\n\n return {\n project: {\n id: projectId,\n weaverseShopId: 'shop-id',\n name: 'Section Preview',\n },\n configs,\n page: {\n id: 'weaverse-preview-page',\n name: 'Preview section',\n rootId: '1',\n items: [\n {\n id: '1',\n type: 'main',\n data: {},\n children: sectionId ? [{ id: sectionId }] : [],\n },\n ...items,\n ],\n },\n }\n }\n\n private _getLoadPageInput(input: WeaverseNextLoadPageInput) {\n let {\n cache,\n projectId: routeProjectId,\n ...rest\n } = input as WeaverseNextServerLoadPageInput\n let params: Record<string, unknown> = {}\n for (let [key, value] of Object.entries(rest)) {\n if (value !== undefined) {\n params[key] = value\n }\n }\n return { cache, params, routeProjectId }\n }\n\n private async _resolveLoadPageProjectId(routeProjectId?: string) {\n let effectiveProjectId =\n (typeof routeProjectId === 'string' && routeProjectId.trim()) ||\n (await this.resolveProjectId())\n if (effectiveProjectId) {\n this.configs = this._buildPublicConfigs(effectiveProjectId)\n }\n return effectiveProjectId\n }\n\n private _fetchPagePayload(\n projectId: string,\n params: Record<string, unknown>,\n cache?: WeaverseNextCacheConfig\n ) {\n let i18n = this.requestContext?.i18n ?? this.commerce?.storefront?.i18n\n let url = normalizeNextPageUrl(resolveRequestUrl(this.requestContext))\n let apiUrl = `${this._baseConfigs.weaverseApiBase}/api/public/project`\n let userAgent = this.requestContext?.headers?.get('user-agent') ?? ''\n return this.fetchWithCache<Record<string, unknown>>(apiUrl, {\n method: 'POST',\n body: JSON.stringify({\n projectId,\n url,\n i18n,\n params,\n isDesignMode: this._baseConfigs.isDesignMode,\n }),\n headers: { ...JSON_HEADERS, 'X-Visitor-UA': userAgent },\n ...(cache ?? {}),\n })\n }\n\n private _assertNoPageError(payload: Record<string, unknown>) {\n if ('error' in payload && typeof payload.error === 'string') {\n throw new Error(payload.error)\n }\n }\n\n private _createLoaderData(\n payload: Record<string, unknown>,\n projectId: string\n ): WeaverseNextLoaderData {\n this._assertNoPageError(payload)\n let page = payload.page as WeaverseNextPageData | undefined\n let project = payload.project as WeaverseNextLoaderData['project']\n let pageAssignment = normalizeWeaverseNextPageAssignment(\n payload.pageAssignment\n )\n\n page ??= this._generateFallbackPage(\n '<div style=\"text-align: center;\">Please add new section to start.</div>'\n )\n project ??= {\n id: projectId,\n name: 'Weaverse project not found.',\n weaverseShopId: '',\n }\n if (Array.isArray(page.items) && page.items.length === 0) {\n page.items.push({\n type: 'main',\n id: page.rootId || generateUuid(),\n data: {},\n })\n }\n\n return {\n page,\n project,\n pageAssignment,\n configs: {\n ...this._buildPublicConfigs(projectId),\n requestInfo: buildWeaverseNextRequestInfo(this.requestContext),\n },\n }\n }\n\n private async _runLoaders(data: WeaverseNextLoaderData) {\n this.data = data\n let withLoaders = await runWeaverseComponentLoaders({ client: this, data })\n this.data = withLoaders ?? data\n return this.data\n }\n\n loadPage = async (\n input: WeaverseNextLoadPageInput = {}\n ): Promise<WeaverseNextLoaderData | null> => {\n try {\n let { cache, params, routeProjectId } = this._getLoadPageInput(input)\n let projectId = await this._resolveLoadPageProjectId(routeProjectId)\n if (this._baseConfigs.isPreviewMode) {\n let previewData = this._generatePreviewData(projectId || 'x')\n this.data = previewData\n return previewData\n }\n if (!projectId) {\n throw new Error('Missing Weaverse projectId!')\n }\n\n let payload = await this._fetchPagePayload(projectId, params, cache)\n let data = this._createLoaderData(payload, projectId)\n return await this._runLoaders(data)\n } catch (error) {\n console.error('❌ Page load failed', {\n url: this.requestContext?.url,\n projectId: input.projectId || this.configs.projectId,\n message: error instanceof Error ? error.message : String(error),\n })\n return null\n }\n }\n\n loadThemeSettings = async (\n // Broad param keeps this assignable to `WeaverseNextClient.loadThemeSettings`;\n // only the cache fields below are honored — no request-context override.\n optionsInput:\n | WeaverseNextThemeSettingsOptions\n | WeaverseNextRequestContext = {}\n ): Promise<WeaverseNextThemeSettingsResponse> => {\n let options = optionsInput as WeaverseNextThemeSettingsOptions\n let themeSchema = asThemeSchema(this.themeSchema)\n let defaultThemeSettings = generateDataFromSchema(\n this.themeSchema as SchemaType | undefined\n )\n let staticContent = themeSchema?.i18n?.staticContent\n\n try {\n let projectId = await this.resolveProjectId()\n if (!projectId) {\n throw new Error('Missing Weaverse projectId!')\n }\n\n let { isDesignMode } = this._baseConfigs\n let url = `${this._baseConfigs.weaverseApiBase}/api/public/project_configs`\n let result = await this.fetchWithCache<WeaverseNextThemeSettingsResponse>(\n url,\n {\n method: 'POST',\n body: JSON.stringify({ projectId, isDesignMode }),\n headers: JSON_HEADERS,\n revalidate: options.revalidate,\n tags: options.tags,\n }\n )\n\n if (typeof result !== 'object' || result === null) {\n result = { theme: defaultThemeSettings }\n }\n\n if (themeSchema?.settings || themeSchema?.inspector) {\n if (!result.theme || typeof result.theme !== 'object') {\n result.theme = defaultThemeSettings\n } else {\n result.theme = { ...defaultThemeSettings, ...result.theme }\n }\n }\n\n if (staticContent) {\n result.staticContent = staticContent\n }\n\n if (isDesignMode) {\n result = {\n ...result,\n schema: themeSchema\n ? {\n ...themeSchema,\n settings: themeSchema.settings?.map((group) => ({\n ...group,\n inputs: group?.inputs?.map((inputItem) =>\n typeof inputItem?.condition === 'function'\n ? {\n ...inputItem,\n condition: inputItem.condition.toString(),\n }\n : inputItem\n ),\n })),\n }\n : undefined,\n publicEnv: this._baseConfigs.publicEnv,\n }\n }\n\n return result\n } catch (error) {\n let errorDetails = error instanceof Error ? error.message : String(error)\n console.error('Unable to load theme settings', errorDetails)\n return {\n theme: defaultThemeSettings,\n staticContent,\n _error: errorDetails,\n _loadFailed: true,\n }\n }\n }\n}\n\n/**\n * Create a server-side {@link WeaverseNextServerClient} for Next.js App Router\n * routes / server components.\n *\n * @example\n * ```ts\n * let weaverse = createWeaverseNextServerClient({\n * projectId: process.env.WEAVERSE_PROJECT_ID,\n * components,\n * commerce: { storefront },\n * requestContext: { url, headers, searchParams, i18n },\n * cache: { revalidate: 60, tags: ['weaverse'] },\n * })\n * let data = await weaverse.loadPage({ type: 'INDEX' })\n * let theme = await weaverse.loadThemeSettings()\n * ```\n */\nexport function createWeaverseNextServerClient(\n config: WeaverseNextServerClientConfig\n): WeaverseNextServerClient {\n return new NextServerClient(config)\n}\n\nexport { getContextSearchParams } from './configs'\n"]}
1
+ {"version":3,"sources":["../src/server/configs.ts","../src/server/normalize-page-url.ts","../src/server/revalidate-handler.ts","../src/server/server-client.ts"],"names":["pathname","lastParam"],"mappings":"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","file":"server.mjs","sourcesContent":["import type {\n WeaverseNextBaseConfigs,\n WeaverseNextRequestContext,\n} from '../types'\n\nconst DEFAULT_WEAVERSE_HOST = 'https://studio.weaverse.io'\nconst DEFAULT_WEAVERSE_API_BASE = 'https://api.weaverse.io'\n\n/**\n * Weaverse-controlled apex domains the Studio bridge / data API may be served\n * from (matched on the host itself and any subdomain). Kept in sync with\n * Hydrogen's `isTrustedStudioHost`.\n */\nconst TRUSTED_STUDIO_DOMAINS = ['weaverse.io', 'weaverse.dev']\n\n/**\n * Whether `host` is an origin we trust to resolve page/theme data. The\n * `weaverseHost` query param is attacker-controllable, so a crafted\n * `?weaverseHost=` must be rejected before it can point server-side fetches at\n * an arbitrary origin (SSRF). Only `weaverse.io`/`weaverse.dev` and subdomains\n * over https are trusted.\n */\nfunction isTrustedStudioHost(host: string): boolean {\n let parsed: URL\n try {\n parsed = new URL(host)\n } catch {\n return false\n }\n if (parsed.protocol !== 'https:') {\n return false\n }\n let { hostname } = parsed\n return TRUSTED_STUDIO_DOMAINS.some(\n (domain) => hostname === domain || hostname.endsWith(`.${domain}`)\n )\n}\n\nfunction toUrl(value: string | URL): URL | null {\n try {\n return typeof value === 'string'\n ? new URL(value, 'http://localhost')\n : value\n } catch {\n return null\n }\n}\n\n/**\n * Extract the request search params from the explicit Next request context.\n * Prefers `searchParams`, falls back to parsing `url`.\n */\nexport function getContextSearchParams(\n context?: WeaverseNextRequestContext\n): URLSearchParams {\n if (context?.searchParams) {\n return new URLSearchParams(context.searchParams)\n }\n if (context?.url) {\n let url = toUrl(context.url)\n if (url) {\n return new URLSearchParams(url.searchParams)\n }\n }\n return new URLSearchParams()\n}\n\n/**\n * Last value of a (possibly duplicated) query key. Matches Hydrogen's\n * `getRequestQueries`, which assigns while iterating and so keeps the last\n * occurrence — Studio appends its own control params, so a stale earlier value\n * must not win.\n */\nfunction lastParam(\n searchParams: URLSearchParams,\n key: string\n): string | undefined {\n let values = searchParams.getAll(key)\n return values.length ? values.at(-1) : undefined\n}\n\nfunction coerceBool(value: string | undefined): boolean {\n return value === 'true'\n}\n\nfunction readEnv(\n env: Record<string, string | undefined> | undefined,\n key: string\n): string | undefined {\n let fromConfig = env?.[key]\n if (fromConfig !== undefined) {\n return fromConfig\n }\n if (typeof process !== 'undefined' && process.env) {\n return process.env[key]\n }\n return\n}\n\n/** Overrides used while resolving request-scoped Weaverse configuration. */\nexport interface ResolveConfigsOptions {\n /** Environment values; missing keys fall back to `process.env`. */\n env?: Record<string, string | undefined>\n /** Public data API base override. */\n weaverseApiBase?: string\n /** Studio origin override. */\n weaverseHost?: string\n /** Studio asset version override. */\n weaverseVersion?: string\n}\n\n/**\n * Derive Weaverse configs from the request context and env, close to Hydrogen's\n * `getWeaverseConfigs`. Resolves the trusted host, public API base, design /\n * preview / revision flags, and public env — but never resolves the final\n * `projectId` (that priority chain, which may call an async resolver, lives in\n * the server client). Query/env projectId candidates are returned for the\n * client to combine with function/string inputs.\n */\nexport function getWeaverseNextConfigs(\n context?: WeaverseNextRequestContext,\n options: ResolveConfigsOptions = {}\n): WeaverseNextBaseConfigs {\n let searchParams = getContextSearchParams(context)\n let { env } = options\n\n let queryHost = lastParam(searchParams, 'weaverseHost')\n // A trusted query host is canonicalized to its origin before use, so a crafted\n // `?weaverseHost=https://studio.weaverse.io/evil?x=1` can only ever resolve to\n // `https://studio.weaverse.io` — never carrying an attacker path/query into the\n // server-side API base.\n let trustedUrlHost =\n queryHost && isTrustedStudioHost(queryHost) ? new URL(queryHost).origin : ''\n\n let configuredHost =\n options.weaverseHost || readEnv(env, 'WEAVERSE_HOST') || ''\n let weaverseHost = trustedUrlHost || configuredHost || DEFAULT_WEAVERSE_HOST\n\n // Public data reads default to the edge proxy, but an explicit custom host\n // (staging/self-hosted Weaverse) must stay the API base so those deployments\n // don't fetch page/config data from the production proxy.\n let weaverseApiBase =\n trustedUrlHost ||\n options.weaverseApiBase ||\n readEnv(env, 'WEAVERSE_PUBLIC_API_BASE') ||\n (configuredHost && configuredHost !== DEFAULT_WEAVERSE_HOST\n ? configuredHost\n : DEFAULT_WEAVERSE_API_BASE)\n\n let isRevisionPreview =\n context?.isRevisionPreview ?? searchParams.has('__revisionId')\n let isDesignMode =\n context?.isDesignMode ?? coerceBool(lastParam(searchParams, 'isDesignMode'))\n let isPreviewMode =\n context?.isPreviewMode ??\n coerceBool(lastParam(searchParams, 'isPreviewMode'))\n\n return {\n queryProjectId: lastParam(searchParams, 'weaverseProjectId') || '',\n envProjectId: readEnv(env, 'WEAVERSE_PROJECT_ID') || '',\n weaverseHost,\n weaverseApiBase,\n weaverseVersion:\n lastParam(searchParams, 'weaverseVersion') ||\n options.weaverseVersion ||\n '',\n isDesignMode,\n isPreviewMode,\n isRevisionPreview,\n sectionType:\n context?.sectionType || lastParam(searchParams, 'sectionType') || '',\n publicEnv: {\n PUBLIC_STORE_DOMAIN: readEnv(env, 'PUBLIC_STORE_DOMAIN') || '',\n PUBLIC_STOREFRONT_API_TOKEN:\n readEnv(env, 'PUBLIC_STOREFRONT_API_TOKEN') || '',\n },\n }\n}\n","import { withPathPrefix } from '../request-info'\nimport type { WeaverseNextRequestContext } from '../types'\n\n// Query params that influence Weaverse page resolution on the Builder:\n// revision previews, design-mode flags, design-mode draft item overrides,\n// and `weaverse*` control params (host, version, project id). Everything\n// else — utm_*, fbclid, gclid, storefront filters — is irrelevant to which\n// page the Builder returns and would otherwise fragment any fetch cache keyed\n// on the request body. `weaverseDraftItem` is the current draft item param;\n// `__weaverseDraftItem` is kept as a legacy compatibility alias.\nconst KEPT_PARAM_RE =\n /^(?:__revisionId|__weaverseDraftItem|isDesignMode|weaverse)/\nconst DATA_SUFFIX = '.data'\n\n/**\n * Normalize the storefront URL sent in the Builder page API request body.\n *\n * The Builder reads only the pathname (locale/type/handle fallback) and the\n * Weaverse/Studio control params from this URL, so keep exactly those and drop\n * tracking params. Params are sorted for a stable, cache-friendly string.\n *\n * Ported from `@weaverse/hydrogen`'s `normalizePageUrl`, but tolerant of a\n * relative URL (Next route handlers may only know the pathname).\n */\nexport function normalizeNextPageUrl(url: string): string {\n let parsed: URL\n try {\n parsed = new URL(url)\n } catch {\n try {\n parsed = new URL(url, 'http://localhost')\n } catch {\n return url\n }\n }\n\n let kept = [...parsed.searchParams].filter(([key]) => KEPT_PARAM_RE.test(key))\n kept.sort(([a], [b]) => a.localeCompare(b))\n let search = new URLSearchParams(kept).toString()\n\n let { pathname } = parsed\n if (pathname.endsWith(DATA_SUFFIX)) {\n pathname = pathname.slice(0, -DATA_SUFFIX.length)\n }\n return `${parsed.origin}${pathname}${search ? `?${search}` : ''}`\n}\n\n/**\n * Build an absolute-ish request URL string from the explicit request context,\n * preferring `url`, then `pathname` + `searchParams`. Used as the input to\n * {@link normalizeNextPageUrl}.\n */\nexport function resolveRequestUrl(\n context?: WeaverseNextRequestContext\n): string {\n if (context?.url) {\n let raw = String(context.url)\n let url = new URL(raw, 'http://localhost')\n let pathname = withPathPrefix(url.pathname, context.i18n)\n // Unchanged when there is nothing to prefix, so a relative or bare-origin\n // URL is passed on exactly as the app gave it.\n if (pathname === url.pathname) {\n return raw\n }\n url.pathname = pathname\n return url.toString()\n }\n let pathname = withPathPrefix(context?.pathname || '/', context?.i18n)\n let search = context?.searchParams\n ? new URLSearchParams(context.searchParams).toString()\n : ''\n return `http://localhost${pathname}${search ? `?${search}` : ''}`\n}\n","import type { PageType } from '@weaverse/schema'\nimport { PageTypeSchema } from '@weaverse/schema'\nimport {\n ROUTE_CONTEXT_I18N_KEYS,\n sanitizeRouteContextSearch,\n type WeaverseNextRevalidateRouteContext,\n} from '../revalidate-item'\nimport type {\n WeaverseNextComponentData,\n WeaverseNextI18n,\n WeaverseNextRequestContext,\n WeaverseNextServerClient,\n} from '../types'\nimport { generateDataFromSchema } from '../utils'\n\nconst NO_STORE_HEADERS = {\n 'Content-Type': 'application/json',\n 'Cache-Control': 'no-store',\n} as const\n\nconst STATUS_OK = 200\nconst STATUS_BAD_REQUEST = 400\nconst STATUS_NOT_FOUND = 404\nconst STATUS_UNPROCESSABLE = 422\nconst STATUS_SERVER_ERROR = 500\n\nconst MAX_PATHNAME_LENGTH = 2048\nconst MAX_SEARCH_LENGTH = 8192\nconst MAX_HANDLE_LENGTH = 512\nconst MAX_I18N_FIELD_LENGTH = 256\n// ASCII control characters (C0 range + DEL) are never valid in a route path.\n// biome-ignore lint/suspicious/noControlCharactersInRegex: rejecting control chars in untrusted pathnames is the intent.\nconst CONTROL_CHAR_PATTERN = /[\\u0000-\\u001F\\u007F]/\n\n/** Configuration for the App Router item-revalidation handler. */\nexport interface WeaverseNextRevalidateHandlerConfig {\n /**\n * Reuse the app's server-client factory so the loader runs with the same\n * component registry and commerce (storefront) context as page loads.\n *\n * The optional second argument is the validated, same-origin route context\n * reconstructed from the request body. It is `undefined` for legacy bodies\n * that carry no `routeContext`, so a one-argument `(request) => client`\n * callback remains valid. Consumers must still source project ID, Studio\n * host, API bases/keys, and env from server config — never from this\n * browser-provided context.\n */\n getClient: (\n request: Request,\n requestContext?: WeaverseNextRequestContext\n ) => Promise<WeaverseNextServerClient> | WeaverseNextServerClient\n}\n\n/** POST body accepted by the revalidate route. */\nexport interface WeaverseNextRevalidateRequestBody {\n /** Unsaved Studio item settings to pass to the registered component loader. */\n draftItem: WeaverseNextComponentData\n /** Public route identity used to reconstruct the loader request context. */\n routeContext?: WeaverseNextRevalidateRouteContext\n}\n\n/**\n * Whether a browser-provided pathname is safe to reconstruct a same-origin URL\n * from. Rejects protocol-relative (`//`), absolute-URL, backslash, control\n * character, query-in-path, and fragment-in-path inputs before any URL is\n * built. Literal/encoded dot segments are allowed here and normalized later by\n * the URL pathname setter.\n */\nfunction isValidPathname(pathname: string): boolean {\n if (!pathname || pathname.length > MAX_PATHNAME_LENGTH) {\n return false\n }\n if (pathname[0] !== '/' || pathname.startsWith('//')) {\n return false\n }\n if (pathname.includes('\\\\') || pathname.includes('?')) {\n return false\n }\n if (pathname.includes('#') || CONTROL_CHAR_PATTERN.test(pathname)) {\n return false\n }\n return true\n}\n\n/**\n * Whether a value is a plain object (literal or `null`-prototype), the only\n * i18n container the wire shape allows. Arrays, class instances, and other\n * exotic objects are rejected so nothing exotic reaches field validation.\n */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false\n }\n let proto = Object.getPrototypeOf(value)\n return proto === Object.prototype || proto === null\n}\n\n/**\n * Validate and pick the allowed i18n fields. Returns `undefined` for a valid\n * empty result and `null` for malformed input so the handler can fail closed.\n *\n * The normative i18n shape carries only the {@link ROUTE_CONTEXT_I18N_KEYS}.\n * Malformed input is rejected rather than silently narrowed: any unknown own\n * key (nested object, extra string, anything), a non-plain container (array,\n * class instance), or a known key whose value is not an optional string of at\n * most {@link MAX_I18N_FIELD_LENGTH} characters fails closed.\n */\nfunction sanitizeRouteContextI18n(\n input: unknown\n): WeaverseNextI18n | undefined | null {\n if (input === undefined) {\n return\n }\n if (!isPlainObject(input)) {\n return null\n }\n let source = input\n let allowed = new Set<string>(ROUTE_CONTEXT_I18N_KEYS)\n // Reject unknown own keys instead of dropping them, so a crafted context\n // cannot smuggle extra properties past the trust boundary.\n for (let key of Object.keys(source)) {\n if (!allowed.has(key)) {\n return null\n }\n }\n let result: Record<string, string> = {}\n for (let key of ROUTE_CONTEXT_I18N_KEYS) {\n let value = source[key]\n if (value === undefined) {\n continue\n }\n if (typeof value !== 'string' || value.length > MAX_I18N_FIELD_LENGTH) {\n return null\n }\n result[key] = value\n }\n return Object.keys(result).length ? result : undefined\n}\n\n/**\n * Reconstruct a validated, same-origin {@link WeaverseNextRequestContext} from\n * the untrusted route context. Returns `null` for any malformed field so the\n * handler can answer `400 invalid-route-context` before creating a client. The\n * endpoint origin is fixed first, then validated components are assigned, so\n * the browser cannot change protocol, host, port, or credentials.\n */\nfunction reconstructRouteContext(\n request: Request,\n routeContext: unknown\n): WeaverseNextRequestContext | null {\n if (\n typeof routeContext !== 'object' ||\n routeContext === null ||\n Array.isArray(routeContext)\n ) {\n return null\n }\n let { pathname, search, handle, pageType, i18n } = routeContext as Record<\n string,\n unknown\n >\n\n if (typeof pathname !== 'string' || !isValidPathname(pathname)) {\n return null\n }\n\n if (typeof search !== 'string' || search.length > MAX_SEARCH_LENGTH) {\n return null\n }\n let rawSearch = search\n if (rawSearch.length && !rawSearch.startsWith('?')) {\n return null\n }\n\n let sanitizedI18n = sanitizeRouteContextI18n(i18n)\n if (sanitizedI18n === null) {\n return null\n }\n\n let resolvedPageType: PageType | undefined\n if (pageType !== undefined) {\n let parsed = PageTypeSchema.safeParse(pageType)\n if (!parsed.success) {\n return null\n }\n resolvedPageType = parsed.data\n }\n\n let resolvedHandle: string | undefined\n if (handle !== undefined) {\n if (\n typeof handle !== 'string' ||\n !handle ||\n handle.length > MAX_HANDLE_LENGTH\n ) {\n return null\n }\n resolvedHandle = handle\n }\n\n // Fix the endpoint origin first, then assign validated components. Reuse the\n // URL's canonical pathname in both context fields so raw input never survives\n // in only one place.\n let endpointUrl = new URL(request.url)\n let routeUrl = new URL(endpointUrl.origin)\n routeUrl.pathname = pathname\n routeUrl.search = sanitizeRouteContextSearch(rawSearch)\n let canonicalPathname = routeUrl.pathname\n let searchParams = routeUrl.searchParams\n\n // Last value wins for duplicated Studio controls, matching\n // `getWeaverseNextConfigs()` and its cache-mode resolution.\n let lastParam = (key: string): string | undefined => {\n let values = searchParams.getAll(key)\n return values.length ? values.at(-1) : undefined\n }\n\n return {\n pathname: canonicalPathname,\n searchParams,\n url: routeUrl,\n // Headers come from the actual same-origin POST, never its JSON body.\n headers: new Headers(request.headers),\n ...(sanitizedI18n ? { i18n: sanitizedI18n } : {}),\n ...(resolvedPageType ? { pageType: resolvedPageType } : {}),\n ...(resolvedHandle ? { handle: resolvedHandle } : {}),\n isDesignMode: lastParam('isDesignMode') === 'true',\n isPreviewMode: lastParam('isPreviewMode') === 'true',\n isRevisionPreview: searchParams.has('__revisionId'),\n sectionType: lastParam('sectionType') || undefined,\n }\n}\n\nfunction json(body: Record<string, unknown>, status: number) {\n return new Response(JSON.stringify(body), {\n status,\n headers: NO_STORE_HEADERS,\n })\n}\n\nfunction parseDraftItem(payload: unknown): WeaverseNextComponentData | null {\n if (typeof payload !== 'object' || payload === null) {\n return null\n }\n let draftItem = (payload as { draftItem?: unknown }).draftItem\n if (typeof draftItem !== 'object' || draftItem === null) {\n return null\n }\n let { id, type } = draftItem as { id?: unknown; type?: unknown }\n if (typeof id !== 'string' || !id || typeof type !== 'string' || !type) {\n return null\n }\n return draftItem as WeaverseNextComponentData\n}\n\n/** App Router handler returned for Studio item revalidation requests. */\nexport interface WeaverseNextRevalidateHandler {\n /** Handle a Studio request to rerun one registered component loader. */\n POST: (request: Request) => Promise<Response>\n}\n\n/**\n * Create the Studio per-item revalidation route handler.\n *\n * Studio design-mode edits to loader-backed inputs (e.g. resource pickers) need\n * fresh server loader data for a single item. Re-running it through\n * `router.refresh()` re-applies the whole RSC tree — and the draft-item query\n * rewrite changes the App Router page segment key, remounting the page and\n * resetting scroll. This handler runs just the edited component's `loader`\n * with the unsaved draft settings and returns the payload for an in-place\n * client update (see the `2026-07-02--next-item-revalidation` spec).\n *\n * Security: only registered component types are executable, the handler never\n * persists anything, and responses are `no-store`. Exposure is equivalent to\n * the existing `weaverseDraftItem` URL param, which already lets any visitor\n * run design-mode loaders with arbitrary draft settings.\n *\n * @example\n * ```ts\n * // app/api/weaverse/revalidate/route.ts\n * export const { POST } = createWeaverseNextRevalidateHandler({\n * getClient: () => getWeaverseServerClient(Promise.resolve({})),\n * })\n * ```\n */\nexport function createWeaverseNextRevalidateHandler(\n config: WeaverseNextRevalidateHandlerConfig\n): WeaverseNextRevalidateHandler {\n return {\n POST: async (request: Request) => {\n let payload: unknown\n try {\n payload = await request.json()\n } catch {\n return json({ error: 'invalid-payload' }, STATUS_BAD_REQUEST)\n }\n\n let draftItem = parseDraftItem(payload)\n if (!draftItem) {\n return json({ error: 'invalid-payload' }, STATUS_BAD_REQUEST)\n }\n\n // Missing `routeContext` is valid legacy input; a present but malformed\n // context is rejected at the trust boundary before any client is created.\n let requestContext: WeaverseNextRequestContext | undefined\n let body = payload as { routeContext?: unknown }\n if (Object.hasOwn(body, 'routeContext')) {\n let reconstructed = reconstructRouteContext(request, body.routeContext)\n if (!reconstructed) {\n return json({ error: 'invalid-route-context' }, STATUS_BAD_REQUEST)\n }\n requestContext = reconstructed\n }\n\n let client: WeaverseNextServerClient\n try {\n client = await config.getClient(request, requestContext)\n } catch (error) {\n console.error('❌ Revalidate handler getClient failed.', error)\n return json({ error: 'client-init-failed' }, STATUS_SERVER_ERROR)\n }\n\n let component = client.components.find(\n (candidate) => candidate?.schema?.type === draftItem.type\n )\n if (!component) {\n return json({ error: 'unknown-component-type' }, STATUS_NOT_FOUND)\n }\n if (typeof component.loader !== 'function') {\n return json({ error: 'missing-loader' }, STATUS_UNPROCESSABLE)\n }\n\n try {\n // Same args shape as `runWeaverseComponentLoaders`, so component\n // loaders behave identically between page load and revalidation.\n let loaderData = await component.loader({\n data: {\n ...generateDataFromSchema(component.schema),\n ...draftItem.data,\n },\n weaverse: client,\n context: client.requestContext,\n commerce: client.commerce,\n })\n return json({ loaderData: loaderData ?? null }, STATUS_OK)\n } catch (error) {\n console.error(\n '❌ Item loader revalidation failed.',\n draftItem.type,\n draftItem.id,\n error\n )\n return json({ error: 'loader-failed' }, STATUS_SERVER_ERROR)\n }\n },\n }\n}\n","import type { SchemaType } from '@weaverse/schema'\nimport { runWeaverseComponentLoaders } from '../loader'\nimport { buildWeaverseNextRequestInfo } from '../request-info'\nimport type {\n WeaverseNextBaseConfigs,\n WeaverseNextCacheConfig,\n WeaverseNextCommerceContext,\n WeaverseNextComponent,\n WeaverseNextComponentData,\n WeaverseNextConfigs,\n WeaverseNextCustomPageEntry,\n WeaverseNextFetchCustomPagesOptions,\n WeaverseNextFetchOptions,\n WeaverseNextLoaderData,\n WeaverseNextLoadPageInput,\n WeaverseNextPageAssignment,\n WeaverseNextPageData,\n WeaverseNextProjectId,\n WeaverseNextRequestContext,\n WeaverseNextServerClient,\n WeaverseNextServerClientConfig,\n WeaverseNextServerLoadPageInput,\n WeaverseNextStorefront,\n WeaverseNextThemeSchema,\n WeaverseNextThemeSettingsOptions,\n WeaverseNextThemeSettingsResponse,\n} from '../types'\nimport { generateDataFromSchema } from '../utils'\nimport { getWeaverseNextConfigs } from './configs'\nimport { normalizeNextPageUrl, resolveRequestUrl } from './normalize-page-url'\n\nconst DEFAULT_FETCH_TIMEOUT_MS = 10_000\nconst RANDOM_ID_RADIX = 36\nconst RANDOM_ID_SLICE_START = 2\nconst MAX_CUSTOM_PAGE_PAGES = 100\n\nconst JSON_HEADERS = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'Accept-Encoding': 'gzip, deflate, br',\n} as const\n\n/** Next's `fetch` reads `next: { revalidate, tags }` off the request init. */\ntype NextRequestInit = RequestInit & {\n next?: { revalidate?: number | false; tags?: string[] }\n}\n\ntype LooseThemeSchema = WeaverseNextThemeSchema\n\nfunction asThemeSchema(schema: unknown): LooseThemeSchema | undefined {\n return schema && typeof schema === 'object'\n ? (schema as LooseThemeSchema)\n : undefined\n}\n\nfunction generateUuid(): string {\n if (typeof crypto !== 'undefined' && 'randomUUID' in crypto) {\n return crypto.randomUUID()\n }\n return `id-${Math.random().toString(RANDOM_ID_RADIX).slice(RANDOM_ID_SLICE_START)}`\n}\n\n/**\n * Normalize the raw `pageAssignment` from `/api/public/project` into a\n * save-compatible {@link WeaverseNextPageAssignment} so the Builder Studio save\n * pipeline receives the same shape it gets from Hydrogen. Returns `undefined`\n * for a missing or malformed assignment (rather than fabricating one), requires\n * string `projectId`/`type`/`handle`, coerces a nullish `locale` to `''`, and\n * preserves an object `meta` untouched.\n */\nfunction normalizeWeaverseNextPageAssignment(\n input: unknown\n): WeaverseNextPageAssignment | undefined {\n if (!input || typeof input !== 'object') {\n return\n }\n let { projectId, type, handle, locale, meta } = input as Record<\n string,\n unknown\n >\n if (\n typeof projectId !== 'string' ||\n typeof type !== 'string' ||\n typeof handle !== 'string'\n ) {\n return\n }\n let normalized: WeaverseNextPageAssignment = {\n projectId,\n type,\n handle,\n locale: typeof locale === 'string' ? locale : '',\n }\n if (meta && typeof meta === 'object') {\n normalized.meta = meta as WeaverseNextPageAssignment['meta']\n }\n return normalized\n}\n\n/**\n * Server-side Weaverse client for Next.js. Performs the real Weaverse public\n * API fetch (page + theme settings) instead of delegating to injected fetchers,\n * closing the gap with Hydrogen's `context.weaverse.loadPage(...)`.\n */\nclass NextServerClient implements WeaverseNextServerClient {\n components: WeaverseNextComponent[]\n commerce?: WeaverseNextCommerceContext\n requestContext?: WeaverseNextRequestContext\n themeSchema?: SchemaType | WeaverseNextThemeSchema\n themeSettings: Record<string, unknown>\n data: WeaverseNextLoaderData | null = null\n dataContext: Record<string, unknown> = {}\n configs: WeaverseNextConfigs\n\n private readonly _projectIdInput?: WeaverseNextProjectId\n private readonly _baseConfigs: WeaverseNextBaseConfigs\n private readonly _fetch: typeof fetch\n private readonly _cache?: WeaverseNextServerClientConfig['cache']\n private readonly _fetchTimeoutMs: number\n private _resolvedProjectId?: string\n\n constructor(config: WeaverseNextServerClientConfig) {\n // Server client keeps the component definitions for server-side loaders\n // (`runWeaverseComponentLoaders`) and preview-data generation, but it\n // intentionally does NOT call `registerWeaverseNextComponents`. Registering\n // pulls in `../registry` → `@weaverse/react`, which evaluates\n // `React.createContext()` at module load — invalid in the RSC/server graph\n // and the cause of `(0 , x.createContext) is not a function`. The client\n // wrapper/renderer (root `@weaverse/next` client entry) registers the real\n // render components instead, keeping `@weaverse/next/server` React-free.\n this.components = config.components\n this.commerce = config.commerce\n this.requestContext = config.requestContext\n this.themeSchema = config.themeSchema\n // Seed schema defaults before merchant overrides, mirroring the root client.\n this.themeSettings = {\n ...generateDataFromSchema(config.themeSchema),\n ...config.themeSettings,\n }\n this._projectIdInput = config.projectId\n this._fetch = config.fetch ?? globalThis.fetch\n this._cache = config.cache\n this._fetchTimeoutMs = config.fetchTimeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS\n\n this._baseConfigs = getWeaverseNextConfigs(config.requestContext, {\n env: config.env,\n weaverseHost: config.weaverseHost,\n weaverseApiBase: config.weaverseApiBase,\n weaverseVersion: config.weaverseVersion,\n })\n\n // Synchronous best-effort projectId (query → string → env). A function\n // resolver is awaited lazily in `resolveProjectId`, so `projectId` reflects\n // its result after the first `loadPage`/`loadThemeSettings`/`resolveProjectId`.\n this.configs = this._buildPublicConfigs(\n this._baseConfigs.queryProjectId ||\n (typeof this._projectIdInput === 'string'\n ? this._projectIdInput.trim()\n : '') ||\n this._baseConfigs.envProjectId\n )\n }\n\n get projectId(): string {\n return this.configs.projectId\n }\n\n /** Compatibility alias so loaders can call `weaverse.storefront.query(...)`. */\n get storefront(): WeaverseNextStorefront | undefined {\n return this.commerce?.storefront\n }\n\n private _buildPublicConfigs(projectId: string): WeaverseNextConfigs {\n let base = this._baseConfigs\n return {\n projectId,\n weaverseHost: base.weaverseHost,\n weaverseApiBase: base.weaverseApiBase,\n weaversePublicApiBase: base.weaverseApiBase,\n weaverseVersion: base.weaverseVersion,\n isDesignMode: base.isDesignMode,\n isPreviewMode: base.isPreviewMode,\n isRevisionPreview: base.isRevisionPreview,\n sectionType: base.sectionType,\n publicEnv: base.publicEnv,\n }\n }\n\n resolveProjectId = async (): Promise<string> => {\n if (this._resolvedProjectId !== undefined) {\n return this._resolvedProjectId\n }\n\n // Priority: query param → function → string → env (matches Hydrogen).\n let resolved = this._baseConfigs.queryProjectId\n if (!resolved && typeof this._projectIdInput === 'function') {\n try {\n let value = await this._projectIdInput(this.requestContext)\n if (typeof value === 'string' && value.trim()) {\n resolved = value.trim()\n }\n } catch (error) {\n console.warn(\n '[WeaverseNextServerClient] projectId resolver threw, falling back.',\n error\n )\n }\n }\n if (!resolved && typeof this._projectIdInput === 'string') {\n resolved = this._projectIdInput.trim()\n }\n if (!resolved) {\n resolved = this._baseConfigs.envProjectId\n }\n\n this._resolvedProjectId = resolved\n this.configs = this._buildPublicConfigs(resolved)\n return resolved\n }\n\n fetchWithCache = async <T = unknown>(\n url: string,\n options: WeaverseNextFetchOptions = {}\n ): Promise<T> => {\n let { revalidate, tags, ...init } = options\n let requestInit: NextRequestInit = { ...init }\n\n let { isDesignMode, isRevisionPreview } = this._baseConfigs\n if (isDesignMode || isRevisionPreview) {\n // Design / revision data must never be served stale.\n requestInit.cache = 'no-store'\n } else if (requestInit.cache === undefined) {\n let effectiveRevalidate = revalidate ?? this._cache?.revalidate\n let effectiveTags = tags ?? this._cache?.tags\n if (effectiveRevalidate !== undefined || effectiveTags?.length) {\n requestInit.next = {\n ...(effectiveRevalidate === undefined\n ? {}\n : { revalidate: effectiveRevalidate }),\n ...(effectiveTags?.length ? { tags: effectiveTags } : {}),\n }\n }\n }\n\n let controller = new AbortController()\n let timeoutId = setTimeout(() => controller.abort(), this._fetchTimeoutMs)\n try {\n let response = await this._fetch(url, {\n ...requestInit,\n signal: requestInit.signal ?? controller.signal,\n })\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n return (await response.json()) as T\n } finally {\n clearTimeout(timeoutId)\n }\n }\n\n private _buildCustomPagesUrl(\n projectId: string,\n options: WeaverseNextFetchCustomPagesOptions,\n cursor: string | null\n ) {\n let params = new URLSearchParams()\n if (options.locale) {\n params.set('locale', options.locale)\n }\n if (options.limit) {\n params.set('limit', String(options.limit))\n }\n if (cursor) {\n params.set('cursor', cursor)\n }\n let qs = params.toString()\n return `${this._baseConfigs.weaverseApiBase}/api/public/v1/projects/${projectId}/custom-pages${\n qs ? `?${qs}` : ''\n }`\n }\n\n /**\n * Fetch all published custom pages for sitemap generation. Mirrors Hydrogen's\n * helper but uses Next's fetch cache knobs (`revalidate` / `tags`). It returns\n * accumulated results on partial pagination failure so a single API hiccup\n * does not break sitemap generation entirely.\n */\n fetchCustomPages = async (\n options: WeaverseNextFetchCustomPagesOptions = {}\n ): Promise<WeaverseNextCustomPageEntry[]> => {\n let projectId = await this.resolveProjectId()\n let entries: WeaverseNextCustomPageEntry[] = []\n if (!projectId) {\n console.warn(\n '[WeaverseNext] Failed to fetch custom pages: missing projectId'\n )\n return entries\n }\n\n let cursor: string | null = null\n for (let page = 0; page < MAX_CUSTOM_PAGE_PAGES; page += 1) {\n let url = this._buildCustomPagesUrl(projectId, options, cursor)\n\n try {\n let result = await this.fetchWithCache<{\n data?: WeaverseNextCustomPageEntry[]\n nextCursor?: string | null\n }>(url, {\n revalidate: options.revalidate,\n tags: options.tags,\n })\n entries.push(...(result.data ?? []))\n if (!result.nextCursor) {\n return entries\n }\n cursor = result.nextCursor\n } catch (error) {\n let message = error instanceof Error ? error.message : String(error)\n console.warn(\n entries.length === 0\n ? `[WeaverseNext] Failed to fetch custom pages: ${message}`\n : `[WeaverseNext] Custom pages pagination interrupted: ${message}`\n )\n return entries\n }\n }\n\n console.warn('[WeaverseNext] Custom pages pagination cap reached')\n return entries\n }\n\n private _generateFallbackPage(message: string): WeaverseNextPageData {\n let rootId = generateUuid()\n return {\n id: `fallback_page_${rootId}`,\n rootId,\n name: 'Default Page',\n items: [\n {\n type: 'main',\n id: rootId,\n data: { dangerouslySetInnerHTML: { __html: message } },\n },\n ],\n }\n }\n\n /**\n * Recursively materialize a section preset (and its preset children) into a\n * flat list of page items, returning the new item id. Ported from Hydrogen's\n * `recursivelyAddDataItem`. Returns `undefined` when the type isn't registered.\n */\n private _buildPreviewItems(\n type: string,\n items: WeaverseNextComponentData[],\n initData: Record<string, unknown> = {}\n ): string | undefined {\n let component = this.components.find((c) => c.schema?.type === type)\n if (!component) {\n return\n }\n let { children, ...data } = (component.schema?.presets ?? {}) as {\n children?: { type: string; [key: string]: unknown }[]\n [key: string]: unknown\n }\n let childIds: { id: string }[] = []\n if (children) {\n for (let child of children) {\n let { type: childType, children: _children, ...childData } = child\n let childId = this._buildPreviewItems(childType, items, childData)\n if (childId) {\n childIds.push({ id: childId })\n }\n }\n }\n let id = generateUuid()\n items.push({ id, type, data: { ...data, ...initData }, children: childIds })\n return id\n }\n\n /**\n * Synthetic loader data for Studio \"section preview\" mode. Mirrors Hydrogen's\n * `getPreviewData`: it builds a single-section page from the requested\n * `sectionType`'s presets without hitting `/api/public/project`, so preview\n * works even without a resolved `projectId`.\n */\n private _generatePreviewData(projectId: string): WeaverseNextLoaderData {\n let { sectionType, weaverseHost } = this._baseConfigs\n let items: WeaverseNextComponentData[] = []\n let sectionId = sectionType\n ? this._buildPreviewItems(sectionType, items)\n : undefined\n\n let configs = {\n ...this._buildPublicConfigs(projectId),\n isPreviewMode: true,\n weaverseHost,\n requestInfo: buildWeaverseNextRequestInfo(this.requestContext),\n }\n\n return {\n project: {\n id: projectId,\n weaverseShopId: 'shop-id',\n name: 'Section Preview',\n },\n configs,\n page: {\n id: 'weaverse-preview-page',\n name: 'Preview section',\n rootId: '1',\n items: [\n {\n id: '1',\n type: 'main',\n data: {},\n children: sectionId ? [{ id: sectionId }] : [],\n },\n ...items,\n ],\n },\n }\n }\n\n private _getLoadPageInput(input: WeaverseNextLoadPageInput) {\n let {\n cache,\n projectId: routeProjectId,\n ...rest\n } = input as WeaverseNextServerLoadPageInput\n let params: Record<string, unknown> = {}\n for (let [key, value] of Object.entries(rest)) {\n if (value !== undefined) {\n params[key] = value\n }\n }\n return { cache, params, routeProjectId }\n }\n\n private async _resolveLoadPageProjectId(routeProjectId?: string) {\n let effectiveProjectId =\n (typeof routeProjectId === 'string' && routeProjectId.trim()) ||\n (await this.resolveProjectId())\n if (effectiveProjectId) {\n this.configs = this._buildPublicConfigs(effectiveProjectId)\n }\n return effectiveProjectId\n }\n\n private _fetchPagePayload(\n projectId: string,\n params: Record<string, unknown>,\n cache?: WeaverseNextCacheConfig\n ) {\n let i18n = this.requestContext?.i18n ?? this.commerce?.storefront?.i18n\n let url = normalizeNextPageUrl(resolveRequestUrl(this.requestContext))\n let apiUrl = `${this._baseConfigs.weaverseApiBase}/api/public/project`\n let userAgent = this.requestContext?.headers?.get('user-agent') ?? ''\n return this.fetchWithCache<Record<string, unknown>>(apiUrl, {\n method: 'POST',\n body: JSON.stringify({\n projectId,\n url,\n i18n,\n params,\n isDesignMode: this._baseConfigs.isDesignMode,\n }),\n headers: { ...JSON_HEADERS, 'X-Visitor-UA': userAgent },\n ...(cache ?? {}),\n })\n }\n\n private _assertNoPageError(payload: Record<string, unknown>) {\n if ('error' in payload && typeof payload.error === 'string') {\n throw new Error(payload.error)\n }\n }\n\n private _createLoaderData(\n payload: Record<string, unknown>,\n projectId: string\n ): WeaverseNextLoaderData {\n this._assertNoPageError(payload)\n let page = payload.page as WeaverseNextPageData | undefined\n let project = payload.project as WeaverseNextLoaderData['project']\n let pageAssignment = normalizeWeaverseNextPageAssignment(\n payload.pageAssignment\n )\n\n page ??= this._generateFallbackPage(\n '<div style=\"text-align: center;\">Please add new section to start.</div>'\n )\n project ??= {\n id: projectId,\n name: 'Weaverse project not found.',\n weaverseShopId: '',\n }\n if (Array.isArray(page.items) && page.items.length === 0) {\n page.items.push({\n type: 'main',\n id: page.rootId || generateUuid(),\n data: {},\n })\n }\n\n return {\n page,\n project,\n pageAssignment,\n configs: {\n ...this._buildPublicConfigs(projectId),\n requestInfo: buildWeaverseNextRequestInfo(this.requestContext),\n },\n }\n }\n\n private async _runLoaders(data: WeaverseNextLoaderData) {\n this.data = data\n let withLoaders = await runWeaverseComponentLoaders({ client: this, data })\n this.data = withLoaders ?? data\n return this.data\n }\n\n loadPage = async (\n input: WeaverseNextLoadPageInput = {}\n ): Promise<WeaverseNextLoaderData | null> => {\n try {\n let { cache, params, routeProjectId } = this._getLoadPageInput(input)\n let projectId = await this._resolveLoadPageProjectId(routeProjectId)\n if (this._baseConfigs.isPreviewMode) {\n let previewData = this._generatePreviewData(projectId || 'x')\n this.data = previewData\n return previewData\n }\n if (!projectId) {\n throw new Error('Missing Weaverse projectId!')\n }\n\n let payload = await this._fetchPagePayload(projectId, params, cache)\n let data = this._createLoaderData(payload, projectId)\n return await this._runLoaders(data)\n } catch (error) {\n console.error('❌ Page load failed', {\n url: this.requestContext?.url,\n projectId: input.projectId || this.configs.projectId,\n message: error instanceof Error ? error.message : String(error),\n })\n return null\n }\n }\n\n /**\n * Resolve the request locale (e.g. `fr-ca`) used for merchant overrides.\n * Unlike Hydrogen — which defaults to `en`/`us` because a Hydrogen\n * storefront always has an i18n context — Next apps may not thread one\n * through, so a missing language or country means \"no explicit locale\" and\n * the translation fetch is skipped rather than guessed.\n */\n private _resolveOverridesLocale(): string | undefined {\n let i18n = this.requestContext?.i18n\n let language =\n typeof i18n?.language === 'string' ? i18n.language.trim() : ''\n let country = typeof i18n?.country === 'string' ? i18n.country.trim() : ''\n if (!(language && country)) {\n return\n }\n return `${language.toLowerCase()}-${country.toLowerCase()}`\n }\n\n /**\n * Fetch locale-specific static-text overrides from the translation API.\n * Ported from Hydrogen's `fetchMerchantOverrides`: skipped entirely when the\n * theme has no `i18n` schema (nothing translatable) or when the request has\n * no explicit locale, and never allowed to fail theme settings.\n */\n private async _fetchMerchantOverrides(\n projectId: string,\n options: WeaverseNextThemeSettingsOptions\n ): Promise<Record<string, unknown> | undefined> {\n let { weaverseHost } = this._baseConfigs\n if (!(asThemeSchema(this.themeSchema)?.i18n && projectId && weaverseHost)) {\n return\n }\n\n let locale = this._resolveOverridesLocale()\n if (!locale) {\n return\n }\n\n let url = `${weaverseHost}/api/translation/static?projectId=${projectId}&locale=${locale}`\n try {\n let overrides = await this.fetchWithCache<Record<string, unknown>>(url, {\n method: 'GET',\n headers: { Accept: 'application/json' },\n revalidate: options.revalidate,\n tags: options.tags,\n })\n return typeof overrides === 'object' && overrides !== null\n ? overrides\n : undefined\n } catch (error) {\n // Translations are additive — a failure must not break theme settings.\n console.warn(\n '[WeaverseNext] Unable to load merchant overrides, using theme defaults:',\n error instanceof Error ? error.message : String(error)\n )\n return\n }\n }\n\n loadThemeSettings = async (\n // Broad param keeps this assignable to `WeaverseNextClient.loadThemeSettings`;\n // only the cache fields below are honored — no request-context override.\n optionsInput:\n | WeaverseNextThemeSettingsOptions\n | WeaverseNextRequestContext = {}\n ): Promise<WeaverseNextThemeSettingsResponse> => {\n let options = optionsInput as WeaverseNextThemeSettingsOptions\n let themeSchema = asThemeSchema(this.themeSchema)\n let defaultThemeSettings = generateDataFromSchema(this.themeSchema)\n let staticContent = themeSchema?.i18n?.staticContent\n\n try {\n let projectId = await this.resolveProjectId()\n if (!projectId) {\n throw new Error('Missing Weaverse projectId!')\n }\n\n let { isDesignMode } = this._baseConfigs\n let url = `${this._baseConfigs.weaverseApiBase}/api/public/project_configs`\n // Project configs and locale overrides are independent reads — mirror\n // Hydrogen and fetch them in parallel instead of serially.\n let [result, merchantOverrides] = await Promise.all([\n this.fetchWithCache<WeaverseNextThemeSettingsResponse>(url, {\n method: 'POST',\n body: JSON.stringify({ projectId, isDesignMode }),\n headers: JSON_HEADERS,\n revalidate: options.revalidate,\n tags: options.tags,\n }),\n this._fetchMerchantOverrides(projectId, options),\n ])\n\n if (typeof result !== 'object' || result === null) {\n result = { theme: defaultThemeSettings }\n }\n\n if (themeSchema?.settings || themeSchema?.inspector) {\n if (!result.theme || typeof result.theme !== 'object') {\n result.theme = defaultThemeSettings\n } else {\n result.theme = { ...defaultThemeSettings, ...result.theme }\n }\n }\n\n if (staticContent) {\n result.staticContent = staticContent\n }\n\n // Only overwrite when the translation API actually returned overrides so\n // a missing/failed fetch can't wipe overrides shipped by project_configs.\n if (merchantOverrides) {\n result.merchantOverrides = merchantOverrides\n }\n\n if (isDesignMode) {\n let serializableSchema: WeaverseNextThemeSchema | undefined =\n themeSchema\n ? {\n ...themeSchema,\n settings: themeSchema.settings?.map((group) => ({\n ...group,\n inputs: group?.inputs?.map((inputItem) =>\n typeof inputItem?.condition === 'function'\n ? {\n ...inputItem,\n condition: inputItem.condition.toString(),\n }\n : inputItem\n ),\n })),\n }\n : undefined\n result = {\n ...result,\n schema: serializableSchema,\n publicEnv: this._baseConfigs.publicEnv,\n }\n }\n\n return result\n } catch (error) {\n let errorDetails = error instanceof Error ? error.message : String(error)\n console.error('Unable to load theme settings', errorDetails)\n return {\n theme: defaultThemeSettings,\n staticContent,\n _error: errorDetails,\n _loadFailed: true,\n }\n }\n }\n}\n\n/**\n * Create a server-side {@link WeaverseNextServerClient} for Next.js App Router\n * routes / server components.\n *\n * @example\n * ```ts\n * let weaverse = createWeaverseNextServerClient({\n * projectId: process.env.WEAVERSE_PROJECT_ID,\n * components,\n * commerce: { storefront },\n * requestContext: { url, headers, searchParams, i18n },\n * cache: { revalidate: 60, tags: ['weaverse'] },\n * })\n * let data = await weaverse.loadPage({ type: 'INDEX' })\n * let theme = await weaverse.loadThemeSettings()\n * ```\n */\nexport function createWeaverseNextServerClient(\n config: WeaverseNextServerClientConfig\n): WeaverseNextServerClient {\n return new NextServerClient(config)\n}\n\nexport { getContextSearchParams } from './configs'\n"]}
@@ -0,0 +1,16 @@
1
+ import type { WeaverseNextClient, WeaverseNextClientConfig } from './types';
2
+ /**
3
+ * Create a {@link WeaverseNextClient} from explicit config.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * let client = createWeaverseNextClient({
8
+ * projectId: process.env.WEAVERSE_PROJECT_ID!,
9
+ * components,
10
+ * commerce: { storefront },
11
+ * fetchPage: async ({ type, handle }) => fetchWeaversePage({ type, handle }),
12
+ * })
13
+ * ```
14
+ */
15
+ export declare function createWeaverseNextClient(config: WeaverseNextClientConfig): WeaverseNextClient;
16
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAClB,wBAAwB,EAQzB,MAAM,SAAS,CAAA;AAwEhB;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,kBAAkB,CAEpB"}