@vtex/faststore-plugin-buyer-portal 1.1.98 → 1.1.99

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtex/faststore-plugin-buyer-portal",
3
- "version": "1.1.98",
3
+ "version": "1.1.99",
4
4
  "description": "A plugin for faststore with buyer portal",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -3,6 +3,7 @@
3
3
  import React, { Component, type ReactNode } from "react";
4
4
 
5
5
  import { ErrorTabsLayout } from "../../layouts/ErrorTabsLayout/ErrorTabsLayout";
6
+ import { isPluginError } from "../../utils/isPluginError";
6
7
 
7
8
  interface Props {
8
9
  children: ReactNode;
@@ -26,11 +27,15 @@ export class ErrorBoundary extends Component<Props, State> {
26
27
  }
27
28
 
28
29
  static getDerivedStateFromError(error: Error): State {
29
- return { hasError: true, error };
30
+ if (isPluginError(error)) {
31
+ return { hasError: true, error };
32
+ }
33
+
34
+ return { hasError: false };
30
35
  }
31
36
 
32
37
  componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
33
- if (this.props.onError) {
38
+ if (isPluginError(error) && this.props.onError) {
34
39
  this.props.onError(error, errorInfo);
35
40
  }
36
41
  }
@@ -33,5 +33,7 @@ export {
33
33
  } from "./search";
34
34
  export { toQueryParams } from "./toQueryParams";
35
35
  export { getValidPage } from "./getValidPage";
36
+ export { isPluginError } from "./isPluginError";
37
+ export { useRouteTabsLayoutWithRetry } from "./routeLayoutMapping";
36
38
  export { withLoaderErrorBoundary } from "./withLoaderErrorBoundary";
37
39
  export { withClientErrorBoundary } from "./withClientErrorBoundary";
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Checks if an error originates from the plugin's source files
3
+ * @param error - The error object to check
4
+ * @returns {boolean} True if the error comes from plugin source files, false otherwise
5
+ */
6
+ export function isPluginError(error: Error): boolean {
7
+ if (!error.stack) {
8
+ return false;
9
+ }
10
+
11
+ const stackLines = error.stack.split("\n");
12
+
13
+ const pluginSourcePattern = /\/src\//;
14
+
15
+ for (const line of stackLines) {
16
+ if (pluginSourcePattern.test(line)) {
17
+ return true;
18
+ }
19
+ }
20
+
21
+ return false;
22
+ }
@@ -105,64 +105,138 @@ export const ROUTE_TABS_LAYOUT_MAPPING: Record<string, RouteTabsLayoutConfig> =
105
105
  export function getTabsLayoutConfigFromRoute(
106
106
  pathname: string
107
107
  ): RouteTabsLayoutConfig | null {
108
- const normalizedPath = pathname.split("?")[0].split("#")[0];
108
+ try {
109
+ if (!pathname) {
110
+ return null;
111
+ }
109
112
 
110
- if (ROUTE_TABS_LAYOUT_MAPPING[normalizedPath]) {
111
- return ROUTE_TABS_LAYOUT_MAPPING[normalizedPath];
112
- }
113
+ const normalizedPath = pathname.split("?")[0].split("#")[0];
113
114
 
114
- for (const [routePattern, config] of Object.entries(
115
- ROUTE_TABS_LAYOUT_MAPPING
116
- )) {
117
- if (matchesRoutePattern(normalizedPath, routePattern)) {
118
- return config;
115
+ if (ROUTE_TABS_LAYOUT_MAPPING[normalizedPath]) {
116
+ return ROUTE_TABS_LAYOUT_MAPPING[normalizedPath];
117
+ }
118
+
119
+ for (const [routePattern, config] of Object.entries(
120
+ ROUTE_TABS_LAYOUT_MAPPING
121
+ )) {
122
+ if (matchesRoutePattern(normalizedPath, routePattern)) {
123
+ return config;
124
+ }
119
125
  }
120
- }
121
126
 
122
- return null;
127
+ return null;
128
+ } catch (error) {
129
+ console.warn(
130
+ `Failed to get tabs layout config for pathname "${pathname}":`,
131
+ error
132
+ );
133
+ return null;
134
+ }
123
135
  }
124
136
 
125
137
  function matchesRoutePattern(pathname: string, pattern: string): boolean {
126
- const regexPattern = pattern
127
- .replace(/\[([^\]]+)\]/g, "([^/]+)")
128
- .replace(/\//g, "\\/");
138
+ try {
139
+ if (!pathname || !pattern) {
140
+ return false;
141
+ }
129
142
 
130
- const regex = new RegExp(`^${regexPattern}$`);
131
- return regex.test(pathname);
143
+ const regexPattern = pattern
144
+ .replace(/\[([^\]]+)\]/g, "([^/]+)")
145
+ .replace(/\//g, "\\/");
146
+
147
+ const regex = new RegExp(`^${regexPattern}$`);
148
+ return regex.test(pathname);
149
+ } catch (error) {
150
+ console.warn(
151
+ `Failed to match route pattern "${pattern}" with pathname "${pathname}":`,
152
+ error
153
+ );
154
+ return false;
155
+ }
132
156
  }
133
157
 
134
158
  export function extractRouteParams(pathname: string): Record<string, string> {
135
159
  const params: Record<string, string> = {};
136
160
 
137
- const normalizedPath = pathname.split("?")[0].split("#")[0];
138
-
139
- for (const [routePattern] of Object.entries(ROUTE_TABS_LAYOUT_MAPPING)) {
140
- if (matchesRoutePattern(normalizedPath, routePattern)) {
141
- const paramNames =
142
- routePattern.match(/\[([^\]]+)\]/g)?.map((p) => p.slice(1, -1)) || [];
143
-
144
- const regexPattern = routePattern
145
- .replace(/\[([^\]]+)\]/g, "([^/]+)")
146
- .replace(/\//g, "\\/");
147
- const regex = new RegExp(`^${regexPattern}$`);
161
+ try {
162
+ if (!pathname) {
163
+ return params;
164
+ }
148
165
 
149
- const match = normalizedPath.match(regex);
150
- if (match) {
151
- paramNames.forEach((name, index) => {
152
- params[name] = match[index + 1];
153
- });
166
+ const normalizedPath = pathname.split("?")[0].split("#")[0];
167
+
168
+ for (const [routePattern] of Object.entries(ROUTE_TABS_LAYOUT_MAPPING)) {
169
+ if (matchesRoutePattern(normalizedPath, routePattern)) {
170
+ const paramNames =
171
+ routePattern.match(/\[([^\]]+)\]/g)?.map((p) => p.slice(1, -1)) || [];
172
+
173
+ try {
174
+ const regexPattern = routePattern
175
+ .replace(/\[([^\]]+)\]/g, "([^/]+)")
176
+ .replace(/\//g, "\\/");
177
+ const regex = new RegExp(`^${regexPattern}$`);
178
+
179
+ const match = normalizedPath.match(regex);
180
+ if (match) {
181
+ paramNames.forEach((name, index) => {
182
+ params[name] = match[index + 1];
183
+ });
184
+ }
185
+ } catch (regexError) {
186
+ console.warn(
187
+ `Failed to create regex for pattern "${routePattern}":`,
188
+ regexError
189
+ );
190
+ continue;
191
+ }
192
+ break;
154
193
  }
155
- break;
156
194
  }
195
+ } catch (error) {
196
+ console.warn(
197
+ `Failed to extract route params from pathname "${pathname}":`,
198
+ error
199
+ );
157
200
  }
158
201
 
159
202
  return params;
160
203
  }
161
204
 
162
205
  export function useRouteTabsLayout(pathname: string) {
163
- const config = getTabsLayoutConfigFromRoute(pathname);
206
+ try {
207
+ if (!pathname) {
208
+ return {
209
+ hasTabsLayout: false,
210
+ layoutType: null,
211
+ layoutConfig: null,
212
+ routeParams: {},
213
+ };
214
+ }
215
+
216
+ const config = getTabsLayoutConfigFromRoute(pathname);
217
+
218
+ if (!config) {
219
+ return {
220
+ hasTabsLayout: false,
221
+ layoutType: null,
222
+ layoutConfig: null,
223
+ routeParams: {},
224
+ };
225
+ }
226
+
227
+ const params = extractRouteParams(pathname);
164
228
 
165
- if (!config) {
229
+ return {
230
+ hasTabsLayout: true,
231
+ layoutType: config.layout,
232
+ layoutConfig: config,
233
+ routeParams: params,
234
+ };
235
+ } catch (error) {
236
+ console.warn(
237
+ `Failed to get route tabs layout for pathname "${pathname}":`,
238
+ error
239
+ );
166
240
  return {
167
241
  hasTabsLayout: false,
168
242
  layoutType: null,
@@ -170,13 +244,4 @@ export function useRouteTabsLayout(pathname: string) {
170
244
  routeParams: {},
171
245
  };
172
246
  }
173
-
174
- const params = extractRouteParams(pathname);
175
-
176
- return {
177
- hasTabsLayout: true,
178
- layoutType: config.layout,
179
- layoutConfig: config,
180
- routeParams: params,
181
- };
182
247
  }