@weaverse/hydrogen 5.7.0 → 5.8.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.
- package/dist/index.d.mts +357 -10
- package/dist/index.d.ts +357 -10
- package/dist/index.js +418 -79
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +420 -82
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -3
- package/readme.md +91 -1
package/dist/index.js
CHANGED
|
@@ -55,8 +55,9 @@ function useWeaverseDataContext() {
|
|
|
55
55
|
function createWeaverseDataContext(matches) {
|
|
56
56
|
return createFlatDataContext(matches);
|
|
57
57
|
}
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
function isProjectIdFunction(projectId) {
|
|
59
|
+
return typeof projectId === "function";
|
|
60
|
+
}
|
|
60
61
|
var WeaverseError = class _WeaverseError extends Error {
|
|
61
62
|
code;
|
|
62
63
|
statusCode;
|
|
@@ -82,10 +83,14 @@ function hasError(response) {
|
|
|
82
83
|
return typeof response === "object" && response !== null && "error" in response && typeof response.error === "string";
|
|
83
84
|
}
|
|
84
85
|
function isThemeSettingsResponse(data) {
|
|
85
|
-
|
|
86
|
+
if (typeof data !== "object" || data === null) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
const record = data;
|
|
90
|
+
return "theme" in record && typeof record.theme === "object" && record.theme !== null;
|
|
86
91
|
}
|
|
87
92
|
function isValidHydrogenSchema(schema2) {
|
|
88
|
-
return
|
|
93
|
+
return schema$1.isValidSchema(schema2);
|
|
89
94
|
}
|
|
90
95
|
|
|
91
96
|
// src/utils/index.ts
|
|
@@ -111,15 +116,22 @@ function mergeInspectorSettings(settings, inspector, type) {
|
|
|
111
116
|
);
|
|
112
117
|
return deepMergeArrays(settings, inspector);
|
|
113
118
|
}
|
|
114
|
-
function getRequestQueries(request) {
|
|
119
|
+
function getRequestQueries(request, options) {
|
|
115
120
|
let url = new URL(request.url);
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
{
|
|
122
|
-
|
|
121
|
+
let queries = {};
|
|
122
|
+
for (let [key, value] of url.searchParams.entries()) {
|
|
123
|
+
if (options?.allowedKeys && !options.allowedKeys.includes(key)) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (value === "true") {
|
|
127
|
+
queries[key] = true;
|
|
128
|
+
} else if (value === "false") {
|
|
129
|
+
queries[key] = false;
|
|
130
|
+
} else {
|
|
131
|
+
queries[key] = value;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return queries;
|
|
123
135
|
}
|
|
124
136
|
function getWeaverseConfigs(request, env) {
|
|
125
137
|
let queries = getRequestQueries(request);
|
|
@@ -156,7 +168,12 @@ function getWeaverseConfigs(request, env) {
|
|
|
156
168
|
}
|
|
157
169
|
};
|
|
158
170
|
}
|
|
171
|
+
var schemaDefaultsCache = /* @__PURE__ */ new WeakMap();
|
|
159
172
|
function generateDataFromSchema(schema2) {
|
|
173
|
+
const cached = schemaDefaultsCache.get(schema2);
|
|
174
|
+
if (cached) {
|
|
175
|
+
return cached;
|
|
176
|
+
}
|
|
160
177
|
let data = {};
|
|
161
178
|
let inspectorGroups = [];
|
|
162
179
|
const isComponentSchema = (s) => "type" in s && typeof s.type === "string";
|
|
@@ -211,6 +228,7 @@ function generateDataFromSchema(schema2) {
|
|
|
211
228
|
}
|
|
212
229
|
}
|
|
213
230
|
}
|
|
231
|
+
schemaDefaultsCache.set(schema2, data);
|
|
214
232
|
return data;
|
|
215
233
|
}
|
|
216
234
|
function recursivelyAddDataItem(type, components, items, initData) {
|
|
@@ -447,13 +465,16 @@ var WeaverseHydrogenRoot = react$1.memo(
|
|
|
447
465
|
}) => {
|
|
448
466
|
const matches = reactRouter.useMatches();
|
|
449
467
|
const enhancedDataContext = createWeaverseDataContext(matches);
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
468
|
+
const weaverseData = react$1.useMemo(() => {
|
|
469
|
+
for (let i = matches.length - 1; i >= 0; i--) {
|
|
470
|
+
const match = matches[i];
|
|
471
|
+
const loaderData = match.loaderData;
|
|
472
|
+
if (loaderData && "weaverseData" in loaderData) {
|
|
473
|
+
return loaderData.weaverseData;
|
|
474
|
+
}
|
|
455
475
|
}
|
|
456
|
-
|
|
476
|
+
return null;
|
|
477
|
+
}, [matches]);
|
|
457
478
|
if (weaverseData) {
|
|
458
479
|
if (weaverseData instanceof Promise) {
|
|
459
480
|
return /* @__PURE__ */ jsxRuntime.jsx(reactErrorBoundary.ErrorBoundary, { fallbackRender: ErrorComponent, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.Suspense, { children: /* @__PURE__ */ jsxRuntime.jsx(reactRouter.Await, { resolve: weaverseData, children: (resolvedData) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -499,14 +520,19 @@ function useThemeSettings() {
|
|
|
499
520
|
);
|
|
500
521
|
return settings;
|
|
501
522
|
}
|
|
523
|
+
var CACHE_DURATIONS = {
|
|
524
|
+
/** Short cache for frequently changing content (10 seconds) */
|
|
525
|
+
SHORT: 10,
|
|
526
|
+
/** Long cache duration - 23 hours to maximize CDN hits before daily refresh */
|
|
527
|
+
LONG: 82800
|
|
528
|
+
};
|
|
529
|
+
var DEFAULT_FETCH_TIMEOUT_MS = 1e4;
|
|
502
530
|
var API_PATH = "v1";
|
|
503
531
|
var DEFAULT_CACHE_STRATEGY = {
|
|
504
|
-
maxAge:
|
|
505
|
-
sMaxAge:
|
|
506
|
-
staleWhileRevalidate:
|
|
507
|
-
|
|
508
|
-
staleIfError: 82800
|
|
509
|
-
// 23 hours
|
|
532
|
+
maxAge: CACHE_DURATIONS.SHORT,
|
|
533
|
+
sMaxAge: CACHE_DURATIONS.SHORT,
|
|
534
|
+
staleWhileRevalidate: CACHE_DURATIONS.LONG,
|
|
535
|
+
staleIfError: CACHE_DURATIONS.LONG
|
|
510
536
|
};
|
|
511
537
|
var WeaverseClient = class {
|
|
512
538
|
API = API_PATH;
|
|
@@ -523,31 +549,64 @@ var WeaverseClient = class {
|
|
|
523
549
|
env;
|
|
524
550
|
cache;
|
|
525
551
|
waitUntil;
|
|
552
|
+
// Performance optimizations
|
|
553
|
+
parsedUrl;
|
|
554
|
+
componentsByType;
|
|
555
|
+
// Configuration
|
|
556
|
+
fetchTimeoutMs;
|
|
526
557
|
constructor(args) {
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
this.
|
|
538
|
-
this.
|
|
539
|
-
this.
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
558
|
+
this.request = args.request;
|
|
559
|
+
this.storefront = args.storefront;
|
|
560
|
+
this.customerAccount = args.customerAccount;
|
|
561
|
+
this.components = args.components;
|
|
562
|
+
this.themeSchema = args.themeSchema;
|
|
563
|
+
this.env = args.env;
|
|
564
|
+
this.cache = args.cache;
|
|
565
|
+
this.waitUntil = args.waitUntil;
|
|
566
|
+
this.parsedUrl = new URL(args.request.url);
|
|
567
|
+
this.componentsByType = this.buildComponentLookupMap(args.components);
|
|
568
|
+
this.fetchTimeoutMs = args.fetchTimeoutMs || DEFAULT_FETCH_TIMEOUT_MS;
|
|
569
|
+
this.initializeCache(args);
|
|
570
|
+
this.initializeConfigs(args);
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Initialize Hydrogen cache with proper configuration.
|
|
574
|
+
* Logs warning if waitUntil is missing.
|
|
575
|
+
*/
|
|
576
|
+
initializeCache(args) {
|
|
577
|
+
if (!args.waitUntil) {
|
|
578
|
+
console.warn(
|
|
579
|
+
"\u26A0\uFE0F WeaverseClient: waitUntil not provided, background operations may not complete"
|
|
580
|
+
);
|
|
581
|
+
}
|
|
545
582
|
this.withCache = hydrogen.createWithCache({
|
|
546
|
-
cache,
|
|
547
|
-
waitUntil: waitUntil || (() => Promise.resolve()),
|
|
548
|
-
request
|
|
583
|
+
cache: args.cache,
|
|
584
|
+
waitUntil: args.waitUntil || (() => Promise.resolve()),
|
|
585
|
+
request: args.request
|
|
549
586
|
});
|
|
550
|
-
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Initialize configs with projectId resolution and fail-fast validation.
|
|
590
|
+
* Throws WeaverseError if projectId cannot be resolved.
|
|
591
|
+
*/
|
|
592
|
+
initializeConfigs(args) {
|
|
593
|
+
let baseConfigs = getWeaverseConfigs(args.request, args.env);
|
|
594
|
+
let resolvedProjectId = this.resolveProjectIdSync(
|
|
595
|
+
args.projectId,
|
|
596
|
+
args.request,
|
|
597
|
+
args.env,
|
|
598
|
+
baseConfigs
|
|
599
|
+
);
|
|
600
|
+
if (!resolvedProjectId || resolvedProjectId.trim() === "") {
|
|
601
|
+
throw new WeaverseError(
|
|
602
|
+
"Failed to initialize WeaverseClient: No valid projectId found. Set WEAVERSE_PROJECT_ID environment variable or provide projectId parameter.",
|
|
603
|
+
"MISSING_PROJECT_ID"
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
this.configs = {
|
|
607
|
+
...baseConfigs,
|
|
608
|
+
projectId: resolvedProjectId
|
|
609
|
+
};
|
|
551
610
|
this.basePageConfigs = {
|
|
552
611
|
projectId: this.configs.projectId,
|
|
553
612
|
weaverseHost: this.configs.weaverseHost,
|
|
@@ -558,35 +617,240 @@ var WeaverseClient = class {
|
|
|
558
617
|
};
|
|
559
618
|
this.basePageRequestBody = {
|
|
560
619
|
isDesignMode: this.configs.isDesignMode,
|
|
561
|
-
i18n: storefront.i18n,
|
|
620
|
+
i18n: args.storefront.i18n,
|
|
562
621
|
projectId: this.configs.projectId
|
|
563
622
|
};
|
|
623
|
+
Object.freeze(this.configs);
|
|
624
|
+
Object.freeze(this.basePageConfigs);
|
|
625
|
+
Object.freeze(this.basePageRequestBody);
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Build component lookup map for O(1) access by type.
|
|
629
|
+
* Significantly improves performance for large component lists.
|
|
630
|
+
*/
|
|
631
|
+
buildComponentLookupMap(components) {
|
|
632
|
+
return new Map(components.map((comp) => [comp.schema?.type, comp]));
|
|
564
633
|
}
|
|
565
|
-
|
|
566
|
-
|
|
634
|
+
/**
|
|
635
|
+
* Extract comprehensive error information from unknown error type.
|
|
636
|
+
* Preserves error context, codes, and stack traces for debugging.
|
|
637
|
+
*
|
|
638
|
+
* @param error - Unknown error to extract information from
|
|
639
|
+
* @returns Structured error information with message, code, stack, and context
|
|
640
|
+
*
|
|
641
|
+
* @example
|
|
642
|
+
* ```typescript
|
|
643
|
+
* try {
|
|
644
|
+
* // ... operation
|
|
645
|
+
* } catch (error) {
|
|
646
|
+
* const errorInfo = this.extractErrorInfo(error)
|
|
647
|
+
* console.error('Operation failed:', errorInfo.message, errorInfo.context)
|
|
648
|
+
* }
|
|
649
|
+
* ```
|
|
650
|
+
*/
|
|
651
|
+
extractErrorInfo(error) {
|
|
652
|
+
if (error instanceof WeaverseError) {
|
|
653
|
+
return {
|
|
654
|
+
message: error.message,
|
|
655
|
+
code: error.code,
|
|
656
|
+
context: error.context,
|
|
657
|
+
stack: error.stack
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
if (error instanceof Error) {
|
|
661
|
+
return {
|
|
662
|
+
message: error.message,
|
|
663
|
+
stack: error.stack
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
return {
|
|
667
|
+
message: String(error)
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* Extract error message only (for backward compatibility).
|
|
672
|
+
* Use extractErrorInfo() for more detailed error information.
|
|
673
|
+
*
|
|
674
|
+
* @deprecated Use extractErrorInfo() instead to preserve error context
|
|
675
|
+
*/
|
|
676
|
+
extractErrorMessage(error) {
|
|
677
|
+
return this.extractErrorInfo(error).message;
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Validates projectId format (alphanumeric, hyphens, underscores only).
|
|
681
|
+
* Returns detailed validation result with error message.
|
|
682
|
+
*
|
|
683
|
+
* @param projectId - Project identifier to validate
|
|
684
|
+
* @returns Validation result with error message if invalid
|
|
685
|
+
*/
|
|
686
|
+
validateProjectId(projectId) {
|
|
687
|
+
if (!projectId || projectId.trim() === "") {
|
|
688
|
+
return {
|
|
689
|
+
valid: false,
|
|
690
|
+
error: "Project ID cannot be empty"
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
let validPattern = /^[a-zA-Z0-9_-]+$/;
|
|
694
|
+
if (!validPattern.test(projectId)) {
|
|
695
|
+
return {
|
|
696
|
+
valid: false,
|
|
697
|
+
error: `Invalid format: "${projectId}". Only alphanumeric characters, hyphens, and underscores are allowed.`
|
|
698
|
+
};
|
|
699
|
+
}
|
|
700
|
+
return { valid: true };
|
|
701
|
+
}
|
|
702
|
+
/**
|
|
703
|
+
* Resolves projectId with multi-project architecture support.
|
|
704
|
+
* Uses priority chain to determine the correct project ID.
|
|
705
|
+
*
|
|
706
|
+
* @param projectId - Project identifier (string, function, or undefined)
|
|
707
|
+
* @param request - HTTP request for context access
|
|
708
|
+
* @param env - Hydrogen environment with variables
|
|
709
|
+
* @param baseConfigs - Pre-fetched base configs to avoid duplicate calls
|
|
710
|
+
* @returns Resolved project ID string (empty string if none found)
|
|
711
|
+
*/
|
|
712
|
+
resolveProjectIdSync(projectId, request, env, baseConfigs) {
|
|
713
|
+
return this.resolveFromQueryParams(request) || this.resolveFromFunction(projectId) || this.resolveFromString(projectId) || this.resolveFromEnvironment(baseConfigs, request, env) || "";
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* Priority 1: Resolve projectId from URL query parameters.
|
|
717
|
+
* Used for design mode and preview mode overrides.
|
|
718
|
+
*/
|
|
719
|
+
resolveFromQueryParams(request) {
|
|
720
|
+
let queries = getRequestQueries(request);
|
|
721
|
+
return queries.weaverseProjectId || null;
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Priority 2: Resolve projectId from function parameter.
|
|
725
|
+
* Detects and rejects async functions with helpful error.
|
|
726
|
+
*/
|
|
727
|
+
resolveFromFunction(projectId) {
|
|
728
|
+
if (!isProjectIdFunction(projectId)) {
|
|
729
|
+
return null;
|
|
730
|
+
}
|
|
731
|
+
if (projectId.constructor.name === "AsyncFunction") {
|
|
732
|
+
throw new WeaverseError(
|
|
733
|
+
"Async projectId functions must be awaited before passing to WeaverseClient. Use: projectId: await getProjectAsync() instead of: projectId: getProjectAsync",
|
|
734
|
+
"ASYNC_PROJECT_ID"
|
|
735
|
+
);
|
|
736
|
+
}
|
|
567
737
|
try {
|
|
568
|
-
let
|
|
738
|
+
let result = projectId();
|
|
739
|
+
if (result instanceof Promise) {
|
|
740
|
+
throw new WeaverseError(
|
|
741
|
+
"Async projectId functions must be awaited before passing to WeaverseClient. Use: projectId: await getProjectAsync() instead of: projectId: getProjectAsync",
|
|
742
|
+
"ASYNC_PROJECT_ID"
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
if (result && result.trim() !== "") {
|
|
746
|
+
let trimmed = result.trim();
|
|
747
|
+
let validation = this.validateProjectId(trimmed);
|
|
748
|
+
if (validation.valid) {
|
|
749
|
+
return trimmed;
|
|
750
|
+
}
|
|
751
|
+
throw new WeaverseError(
|
|
752
|
+
validation.error || "Invalid projectId format",
|
|
753
|
+
"INVALID_PROJECT_ID"
|
|
754
|
+
);
|
|
755
|
+
}
|
|
756
|
+
} catch (err) {
|
|
757
|
+
if (err instanceof WeaverseError) {
|
|
758
|
+
throw err;
|
|
759
|
+
}
|
|
760
|
+
throw new WeaverseError(
|
|
761
|
+
`Failed to evaluate projectId function: ${err instanceof Error ? err.message : String(err)}`,
|
|
762
|
+
"PROJECT_ID_FUNCTION_ERROR",
|
|
763
|
+
void 0,
|
|
764
|
+
{ cause: err instanceof Error ? err.stack : String(err) }
|
|
765
|
+
);
|
|
766
|
+
}
|
|
767
|
+
return null;
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* Priority 3: Resolve projectId from explicit string parameter.
|
|
771
|
+
*/
|
|
772
|
+
resolveFromString(projectId) {
|
|
773
|
+
if (typeof projectId !== "string") {
|
|
774
|
+
return null;
|
|
775
|
+
}
|
|
776
|
+
let trimmed = projectId.trim();
|
|
777
|
+
if (trimmed === "") {
|
|
778
|
+
return null;
|
|
779
|
+
}
|
|
780
|
+
let validation = this.validateProjectId(trimmed);
|
|
781
|
+
if (validation.valid) {
|
|
782
|
+
return trimmed;
|
|
783
|
+
}
|
|
784
|
+
throw new WeaverseError(
|
|
785
|
+
validation.error || "Invalid projectId format",
|
|
786
|
+
"INVALID_PROJECT_ID"
|
|
787
|
+
);
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* Priority 4: Resolve projectId from environment variables.
|
|
791
|
+
*/
|
|
792
|
+
resolveFromEnvironment(baseConfigs, request, env) {
|
|
793
|
+
let configs = baseConfigs || getWeaverseConfigs(request, env);
|
|
794
|
+
if (configs.projectId && configs.projectId.trim() !== "") {
|
|
795
|
+
return configs.projectId.trim();
|
|
796
|
+
}
|
|
797
|
+
return null;
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Helper method for direct fetching in design mode.
|
|
801
|
+
* Returns same format as withCache.fetch for consistency.
|
|
802
|
+
* Includes 10-second timeout to prevent hanging requests.
|
|
803
|
+
*/
|
|
804
|
+
directFetch = async (url, options = {}, timeoutMs = this.fetchTimeoutMs) => {
|
|
805
|
+
let controller = new AbortController();
|
|
806
|
+
let timeoutId = setTimeout(
|
|
807
|
+
() => controller.abort(),
|
|
808
|
+
timeoutMs
|
|
809
|
+
);
|
|
810
|
+
try {
|
|
811
|
+
let response = await fetch(url, {
|
|
812
|
+
...options,
|
|
813
|
+
signal: controller.signal
|
|
814
|
+
});
|
|
569
815
|
if (!response.ok) {
|
|
570
|
-
let
|
|
571
|
-
throw new
|
|
816
|
+
let errorText = await response.text();
|
|
817
|
+
throw new WeaverseError(
|
|
818
|
+
`HTTP ${response.status}: ${response.statusText}`,
|
|
819
|
+
"FETCH_ERROR",
|
|
820
|
+
response.status,
|
|
821
|
+
{ url, errorText }
|
|
822
|
+
);
|
|
572
823
|
}
|
|
573
824
|
let data = await response.json();
|
|
574
|
-
return {
|
|
575
|
-
data,
|
|
576
|
-
response
|
|
577
|
-
};
|
|
825
|
+
return { data, response };
|
|
578
826
|
} catch (err) {
|
|
579
|
-
|
|
827
|
+
if (err instanceof WeaverseError) {
|
|
828
|
+
throw err;
|
|
829
|
+
}
|
|
830
|
+
if (err.name === "AbortError") {
|
|
831
|
+
throw new WeaverseError(
|
|
832
|
+
`Request timeout after ${timeoutMs}ms`,
|
|
833
|
+
"TIMEOUT_ERROR",
|
|
834
|
+
void 0,
|
|
835
|
+
{ url, timeoutMs }
|
|
836
|
+
);
|
|
837
|
+
}
|
|
838
|
+
throw new WeaverseError(
|
|
839
|
+
"Network error during fetch",
|
|
840
|
+
"NETWORK_ERROR",
|
|
841
|
+
void 0,
|
|
842
|
+
{ url, cause: err instanceof Error ? err.message : String(err) }
|
|
843
|
+
);
|
|
844
|
+
} finally {
|
|
845
|
+
if (timeoutId !== void 0) {
|
|
846
|
+
clearTimeout(timeoutId);
|
|
847
|
+
}
|
|
580
848
|
}
|
|
581
849
|
};
|
|
582
850
|
// Helper method to detect if request is from localhost
|
|
583
851
|
isLocalhost() {
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
return url.hostname === "localhost" || url.hostname === "127.0.0.1";
|
|
587
|
-
} catch {
|
|
588
|
-
return false;
|
|
589
|
-
}
|
|
852
|
+
let hostname = this.parsedUrl.hostname;
|
|
853
|
+
return hostname === "localhost" || hostname === "127.0.0.1";
|
|
590
854
|
}
|
|
591
855
|
// Helper method for building API URLs consistently
|
|
592
856
|
getApiUrl(endpoint, useProxy = !(this.configs.isDesignMode || this.isLocalhost())) {
|
|
@@ -598,7 +862,13 @@ var WeaverseClient = class {
|
|
|
598
862
|
}
|
|
599
863
|
fetchWithCache = async (url, options = {}) => {
|
|
600
864
|
const strategy = options.strategy || this.storefront.CacheCustom(DEFAULT_CACHE_STRATEGY);
|
|
601
|
-
const cacheKey = [
|
|
865
|
+
const cacheKey = [
|
|
866
|
+
"weaverse-fetch",
|
|
867
|
+
url,
|
|
868
|
+
options.method || "GET",
|
|
869
|
+
options.body,
|
|
870
|
+
this.configs.projectId
|
|
871
|
+
];
|
|
602
872
|
let result;
|
|
603
873
|
if (this.configs.isDesignMode) {
|
|
604
874
|
result = await this.directFetch(url, options);
|
|
@@ -678,9 +948,15 @@ var WeaverseClient = class {
|
|
|
678
948
|
};
|
|
679
949
|
}
|
|
680
950
|
return data;
|
|
681
|
-
} catch (
|
|
682
|
-
|
|
683
|
-
|
|
951
|
+
} catch (error) {
|
|
952
|
+
let errorMessage = "Unable to load theme settings";
|
|
953
|
+
let errorDetails = this.extractErrorMessage(error);
|
|
954
|
+
console.error(errorMessage, errorDetails);
|
|
955
|
+
return {
|
|
956
|
+
theme: defaultThemeSettings,
|
|
957
|
+
_error: errorDetails,
|
|
958
|
+
_loadFailed: true
|
|
959
|
+
};
|
|
684
960
|
}
|
|
685
961
|
};
|
|
686
962
|
generateFallbackPage = (message) => {
|
|
@@ -701,16 +977,39 @@ var WeaverseClient = class {
|
|
|
701
977
|
loadPage = async (params = {}) => {
|
|
702
978
|
try {
|
|
703
979
|
let { request, storefront, basePageRequestBody, basePageConfigs } = this;
|
|
704
|
-
let {
|
|
980
|
+
let {
|
|
981
|
+
projectId: clientProjectId,
|
|
982
|
+
weaverseHost,
|
|
983
|
+
isPreviewMode,
|
|
984
|
+
sectionType
|
|
985
|
+
} = this.configs;
|
|
986
|
+
if (params.projectId !== void 0) {
|
|
987
|
+
if (typeof params.projectId !== "string") {
|
|
988
|
+
console.error(
|
|
989
|
+
`Route-level projectId validation failed: must be a string. Received: ${typeof params.projectId}`
|
|
990
|
+
);
|
|
991
|
+
return null;
|
|
992
|
+
}
|
|
993
|
+
let validation = this.validateProjectId(params.projectId);
|
|
994
|
+
if (!validation.valid) {
|
|
995
|
+
console.error(
|
|
996
|
+
`Route-level projectId validation failed: ${validation.error}`
|
|
997
|
+
);
|
|
998
|
+
return null;
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
let effectiveProjectId = params.projectId || clientProjectId;
|
|
705
1002
|
if (isPreviewMode) {
|
|
706
1003
|
return getPreviewData(sectionType || "", this.components, weaverseHost);
|
|
707
1004
|
}
|
|
708
|
-
if (!
|
|
1005
|
+
if (!effectiveProjectId) {
|
|
709
1006
|
throw new Error("Missing Weaverse projectId!");
|
|
710
1007
|
}
|
|
711
1008
|
let { strategy, ...pageLoadParams } = params;
|
|
712
1009
|
let body = {
|
|
713
1010
|
...basePageRequestBody,
|
|
1011
|
+
projectId: effectiveProjectId,
|
|
1012
|
+
// Use effective (potentially overridden) projectId
|
|
714
1013
|
params: pageLoadParams,
|
|
715
1014
|
url: request.url
|
|
716
1015
|
};
|
|
@@ -731,11 +1030,27 @@ var WeaverseClient = class {
|
|
|
731
1030
|
if (hasError(projectData)) {
|
|
732
1031
|
throw new Error(projectData.error);
|
|
733
1032
|
}
|
|
734
|
-
let
|
|
1033
|
+
let page;
|
|
1034
|
+
let project;
|
|
1035
|
+
let pageAssignment;
|
|
1036
|
+
if (isFetchProjectPayload(projectData)) {
|
|
1037
|
+
page = projectData.page;
|
|
1038
|
+
project = projectData.project;
|
|
1039
|
+
pageAssignment = projectData.pageAssignment;
|
|
1040
|
+
} else {
|
|
1041
|
+
console.warn(
|
|
1042
|
+
"Invalid project data structure received from API, using fallback data",
|
|
1043
|
+
{ projectId: effectiveProjectId }
|
|
1044
|
+
);
|
|
1045
|
+
let responseData = projectData;
|
|
1046
|
+
page = responseData?.page;
|
|
1047
|
+
project = responseData?.project;
|
|
1048
|
+
pageAssignment = responseData?.pageAssignment;
|
|
1049
|
+
}
|
|
735
1050
|
if (!project) {
|
|
736
|
-
console.warn("Weaverse project not found. Id:",
|
|
1051
|
+
console.warn("Weaverse project not found. Id:", effectiveProjectId);
|
|
737
1052
|
project = {
|
|
738
|
-
id:
|
|
1053
|
+
id: effectiveProjectId,
|
|
739
1054
|
name: "Weaverse project not found.",
|
|
740
1055
|
weaverseShopId: ""
|
|
741
1056
|
};
|
|
@@ -756,19 +1071,42 @@ var WeaverseClient = class {
|
|
|
756
1071
|
requestInfo: {
|
|
757
1072
|
i18n: storefront.i18n,
|
|
758
1073
|
queries: getRequestQueries(request),
|
|
759
|
-
pathname:
|
|
760
|
-
search:
|
|
1074
|
+
pathname: this.parsedUrl.pathname,
|
|
1075
|
+
search: this.parsedUrl.search
|
|
761
1076
|
}
|
|
762
1077
|
}
|
|
763
1078
|
};
|
|
764
|
-
} catch (
|
|
765
|
-
|
|
1079
|
+
} catch (error) {
|
|
1080
|
+
let errorMessage = "\u274C Page load failed";
|
|
1081
|
+
let errorContext = {
|
|
1082
|
+
url: this.request.url,
|
|
1083
|
+
projectId: params.projectId || this.configs.projectId
|
|
1084
|
+
};
|
|
1085
|
+
if (error instanceof WeaverseError) {
|
|
1086
|
+
console.error(errorMessage, {
|
|
1087
|
+
code: error.code,
|
|
1088
|
+
message: error.message,
|
|
1089
|
+
...errorContext,
|
|
1090
|
+
...error.context
|
|
1091
|
+
});
|
|
1092
|
+
} else if (error instanceof Error) {
|
|
1093
|
+
console.error(errorMessage, {
|
|
1094
|
+
message: error.message,
|
|
1095
|
+
stack: error.stack,
|
|
1096
|
+
...errorContext
|
|
1097
|
+
});
|
|
1098
|
+
} else {
|
|
1099
|
+
console.error(errorMessage, {
|
|
1100
|
+
error: String(error),
|
|
1101
|
+
...errorContext
|
|
1102
|
+
});
|
|
1103
|
+
}
|
|
766
1104
|
return null;
|
|
767
1105
|
}
|
|
768
1106
|
};
|
|
769
1107
|
execComponentLoader = async (item) => {
|
|
770
1108
|
let { data = {}, type, id } = item;
|
|
771
|
-
let component = this.
|
|
1109
|
+
let component = this.componentsByType.get(type);
|
|
772
1110
|
let loader = component?.loader;
|
|
773
1111
|
if (typeof loader === "function" && component) {
|
|
774
1112
|
try {
|
|
@@ -781,8 +1119,8 @@ var WeaverseClient = class {
|
|
|
781
1119
|
})
|
|
782
1120
|
)
|
|
783
1121
|
};
|
|
784
|
-
} catch (
|
|
785
|
-
console.warn("\u274C Item loader run failed.", type, id,
|
|
1122
|
+
} catch (error) {
|
|
1123
|
+
console.warn("\u274C Item loader run failed.", type, id, error);
|
|
786
1124
|
return item;
|
|
787
1125
|
}
|
|
788
1126
|
}
|
|
@@ -868,6 +1206,7 @@ exports.getSelectedProductOptions = getSelectedProductOptions;
|
|
|
868
1206
|
exports.getWeaverseConfigs = getWeaverseConfigs;
|
|
869
1207
|
exports.hasError = hasError;
|
|
870
1208
|
exports.isFetchProjectPayload = isFetchProjectPayload;
|
|
1209
|
+
exports.isProjectIdFunction = isProjectIdFunction;
|
|
871
1210
|
exports.isThemeSettingsResponse = isThemeSettingsResponse;
|
|
872
1211
|
exports.isValidHydrogenSchema = isValidHydrogenSchema;
|
|
873
1212
|
exports.isWithCacheFetchResponse = isWithCacheFetchResponse;
|