@posiwise/common-services 0.1.91 → 0.1.92

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.
@@ -1353,7 +1353,7 @@ class PermissionService {
1353
1353
  // or Pages.Beta or Pages.Alpha
1354
1354
  if (permissionName?.includes('||')) {
1355
1355
  const parts = permissionName.split('||').map(p => p.trim());
1356
- if (this.hasAnyGrantedPermission(parts, user, productSlug)) {
1356
+ if (this.hasAnyGrantedPermission(parts, user)) {
1357
1357
  return true;
1358
1358
  }
1359
1359
  }
@@ -1370,12 +1370,8 @@ class PermissionService {
1370
1370
  // user not logged-in
1371
1371
  return false;
1372
1372
  }
1373
- hasAnyGrantedPermission(parts, user, productSlug = null) {
1374
- return parts.some(part => {
1375
- // Format the permission part with the current subscription slug if needed
1376
- const formattedPart = this.getFormattedPermissionName(part, productSlug);
1377
- return user['auth']?.['granted'][formattedPart];
1378
- });
1373
+ hasAnyGrantedPermission(parts, user) {
1374
+ return parts.some(part => user['auth']?.['granted'][part]);
1379
1375
  }
1380
1376
  handleProductKey(productKey, user, permission_key, permissionName) {
1381
1377
  if (productKey) {
@@ -1407,15 +1403,11 @@ class PermissionService {
1407
1403
  else {
1408
1404
  slugToCheck = productSlug;
1409
1405
  }
1410
- // Only format if we have a valid slug to check
1411
- if (slugToCheck) {
1412
- if (!permissionName.includes(slugToCheck) &&
1413
- permissionName.includes('Pages.Product.')) {
1414
- permissionName = permissionName.replace('Pages.Product.', slugToCheck);
1415
- }
1416
- if (permissionName.includes('Pages.Role.') && !permissionName.includes(slugToCheck)) {
1417
- permissionName = permissionName.replace('Pages.Role.', slugToCheck);
1418
- }
1406
+ if (!permissionName.includes(slugToCheck) && permissionName.includes('Pages.Product.')) {
1407
+ permissionName = permissionName.replace('Pages.Product.', slugToCheck);
1408
+ }
1409
+ if (permissionName.includes('Pages.Role.') && !permissionName.includes(slugToCheck)) {
1410
+ permissionName = permissionName.replace('Pages.Role.', slugToCheck);
1419
1411
  }
1420
1412
  return permissionName;
1421
1413
  }
@@ -1500,8 +1492,7 @@ class PermissionService {
1500
1492
  evaluated = this.isGranted(raw, productKey, permission_key, productSlug);
1501
1493
  }
1502
1494
  else {
1503
- // Pass productSlug to isGranted to ensure slug-aware permission checking
1504
- evaluated = this.isGranted(raw, null, null, productSlug);
1495
+ evaluated = this.isGranted(raw);
1505
1496
  }
1506
1497
  expr += ` ${evaluated} `;
1507
1498
  }
@@ -2806,6 +2797,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
2806
2797
 
2807
2798
  class SentryErrorHandler {
2808
2799
  static { this.sentryInitialized = false; }
2800
+ static { this.unhandledRejectionListenerAttached = false; }
2809
2801
  constructor(appConfigService) {
2810
2802
  this.appConfigService = appConfigService;
2811
2803
  }
@@ -2820,16 +2812,15 @@ class SentryErrorHandler {
2820
2812
  if (env?.integrations?.sentry_config) {
2821
2813
  init({ ...config, ...env.integrations.sentry_config });
2822
2814
  SentryErrorHandler.sentryInitialized = true;
2823
- // Add a global listener for unhandled promise rejections
2824
- window.addEventListener('unhandledrejection', (event) => {
2825
- this.handlePromiseRejection(event);
2826
- });
2815
+ // Add a global listener for unhandled promise rejections (once)
2816
+ if (!SentryErrorHandler.unhandledRejectionListenerAttached) {
2817
+ window.addEventListener('unhandledrejection', (event) => {
2818
+ this.handlePromiseRejection(event);
2819
+ });
2820
+ SentryErrorHandler.unhandledRejectionListenerAttached = true;
2821
+ }
2827
2822
  }
2828
2823
  });
2829
- // Add a global listener for unhandled promise rejections
2830
- window.addEventListener('unhandledrejection', (event) => {
2831
- this.handlePromiseRejection(event);
2832
- });
2833
2824
  }
2834
2825
  async getSentryConfigAsync() {
2835
2826
  return new Promise(resolve => {
@@ -2842,18 +2833,23 @@ class SentryErrorHandler {
2842
2833
  // The previous integration (`BrowserTracing` + `routingInstrumentation`) was part of
2843
2834
  // the legacy `@sentry/angular-ivy` API and isn't available in `@sentry/angular` v10.
2844
2835
  beforeSend(event, hint) {
2836
+ const initialExceptionValuesLength = Array.isArray(event?.exception?.values)
2837
+ ? event.exception.values.length
2838
+ : undefined;
2839
+ const safeIncludes = (val, needle) => typeof val === 'string' && val.includes(needle);
2845
2840
  // Check if the event is of type CloseEvent and ignore it
2846
2841
  if (event?.exception?.values) {
2847
2842
  event.exception.values = event.exception.values.filter(value => {
2848
2843
  // Update the condition based on the actual structure of the event
2849
- return !(value.type === 'CloseEvent' || value.value.includes('CloseEvent'));
2844
+ return !(value.type === 'CloseEvent' ||
2845
+ safeIncludes(value.value, 'CloseEvent'));
2850
2846
  });
2851
2847
  }
2852
2848
  if (event?.exception?.values) {
2853
2849
  event.exception.values = event.exception.values.filter(value => {
2854
2850
  // Check for the specific error message and ignore it
2855
2851
  return !(value.type === 'Error' &&
2856
- value.value.includes('ResizeObserver loop completed'));
2852
+ safeIncludes(value.value, 'ResizeObserver loop completed'));
2857
2853
  });
2858
2854
  }
2859
2855
  // originates from vendor.js file
@@ -2870,21 +2866,21 @@ class SentryErrorHandler {
2870
2866
  if (event?.exception?.values) {
2871
2867
  event.exception.values = event.exception.values.filter(value => {
2872
2868
  return !(value.type === 'ChunkLoadError' ||
2873
- value.value.includes('ChunkLoadError: Loading chunk'));
2869
+ safeIncludes(value.value, 'ChunkLoadError: Loading chunk'));
2874
2870
  });
2875
2871
  }
2876
2872
  // Check if the event is a script loading error and ignore it
2877
2873
  if (event?.exception?.values) {
2878
2874
  event.exception.values = event.exception.values.filter(value => {
2879
2875
  return !(value.type === 'Error' &&
2880
- value.value.includes('Could not load "util"'));
2876
+ safeIncludes(value.value, 'Could not load "util"'));
2881
2877
  });
2882
2878
  }
2883
2879
  // Check if the event is a timeout error and ignore it
2884
2880
  if (event?.exception?.values) {
2885
2881
  event.exception.values = event.exception.values.filter(value => {
2886
2882
  return !(value.type === 'Error' &&
2887
- value.value.includes('Error loading plotly.js library from'));
2883
+ safeIncludes(value.value, 'Error loading plotly.js library from'));
2888
2884
  });
2889
2885
  }
2890
2886
  // Check if the event is related to cross-origin frame access
@@ -2898,16 +2894,6 @@ class SentryErrorHandler {
2898
2894
  return null;
2899
2895
  }
2900
2896
  }
2901
- // Check if the event has an exception and values array
2902
- if (event?.exception?.values) {
2903
- // Filter out events generated by TryCatch and GlobalHandlers
2904
- event.exception.values = event.exception.values.filter(value => {
2905
- const mechanism = value.mechanism;
2906
- return !(mechanism &&
2907
- (mechanism.type === 'TryCatch' ||
2908
- mechanism.type === 'GlobalHandlers'));
2909
- });
2910
- }
2911
2897
  // Check if it's a non-error exception
2912
2898
  const isNonErrorException = event?.exception?.values?.[0]?.value?.startsWith('Non-Error exception captured') ??
2913
2899
  hint?.originalException?.message?.startsWith('Non-Error exception captured');
@@ -2915,6 +2901,14 @@ class SentryErrorHandler {
2915
2901
  // We want to ignore those kinds of errors
2916
2902
  return null;
2917
2903
  }
2904
+ // If we started with exception values but filtered them all out, drop the event.
2905
+ // Otherwise Sentry will group it as an "unlabeled event" and spam the issue stream.
2906
+ if (typeof initialExceptionValuesLength === 'number' &&
2907
+ initialExceptionValuesLength > 0 &&
2908
+ Array.isArray(event?.exception?.values) &&
2909
+ event.exception.values.length === 0) {
2910
+ return null;
2911
+ }
2918
2912
  return event;
2919
2913
  },
2920
2914
  denyUrls: [/drift.*\.js/i, /analytics.*\.js/i, /polyfills.*\.js/i, /vendor.*\.js/i],