@pixelated-tech/components 3.9.17 → 3.10.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 (40) hide show
  1. package/dist/components/admin/site-health/google.api.integration.js +13 -3
  2. package/dist/components/admin/site-health/seo-metrics.config.json +0 -10
  3. package/dist/components/admin/site-health/site-health-cloudwatch.integration.js +10 -3
  4. package/dist/components/admin/site-health/site-health-uptime.integration.js +1 -1
  5. package/dist/components/general/accordion.css +4 -4
  6. package/dist/components/general/faq-accordion.js +4 -2
  7. package/dist/components/general/resume.css +4 -0
  8. package/dist/components/general/utilities.js +6 -0
  9. package/dist/config/pixelated.config.json.enc +1 -1
  10. package/dist/index.adminclient.js +0 -1
  11. package/dist/index.adminserver.js +2 -1
  12. package/dist/scripts/pixelated-eslint-plugin.js +64 -15
  13. package/dist/types/components/admin/site-health/google.api.integration.d.ts.map +1 -1
  14. package/dist/types/components/admin/site-health/site-health-cloudwatch.integration.d.ts.map +1 -1
  15. package/dist/types/components/general/faq-accordion.d.ts.map +1 -1
  16. package/dist/types/components/general/utilities.d.ts +2 -0
  17. package/dist/types/components/general/utilities.d.ts.map +1 -1
  18. package/dist/types/index.adminclient.d.ts +0 -1
  19. package/dist/types/index.adminserver.d.ts +1 -1
  20. package/dist/types/test/test-data.d.ts +1282 -0
  21. package/dist/types/test/test-data.d.ts.map +1 -0
  22. package/dist/types/tests/required-faq.rule.test.d.ts +2 -0
  23. package/dist/types/tests/required-faq.rule.test.d.ts.map +1 -0
  24. package/dist/types/tests/routecache.analytics.consumer.integration.test.d.ts +2 -0
  25. package/dist/types/tests/routecache.analytics.consumer.integration.test.d.ts.map +1 -0
  26. package/dist/types/tests/routecache.consumer.integration.test.d.ts +2 -0
  27. package/dist/types/tests/routecache.consumer.integration.test.d.ts.map +1 -0
  28. package/dist/types/tests/routes-json-smoke.test.d.ts +2 -0
  29. package/dist/types/tests/routes-json-smoke.test.d.ts.map +1 -0
  30. package/dist/types/tests/site-health-cache.unit.test.2.d.ts +2 -0
  31. package/dist/types/tests/site-health-cache.unit.test.2.d.ts.map +1 -0
  32. package/dist/types/tests/site-health-cache.unit.test.d.ts +2 -0
  33. package/dist/types/tests/site-health-cache.unit.test.d.ts.map +1 -0
  34. package/package.json +14 -14
  35. package/dist/components/admin/site-health/site-health-cache.js +0 -23
  36. package/dist/components/config/config.example.js +0 -77
  37. package/dist/types/components/admin/site-health/site-health-cache.d.ts +0 -12
  38. package/dist/types/components/admin/site-health/site-health-cache.d.ts.map +0 -1
  39. package/dist/types/components/config/config.example.d.ts +0 -4
  40. package/dist/types/components/config/config.example.d.ts.map +0 -1
@@ -5,8 +5,10 @@
5
5
  */
6
6
  "use server";
7
7
  import { google } from 'googleapis';
8
- import { RouteCache } from './site-health-cache';
8
+ import { CacheManager } from '../../general/cache-manager';
9
9
  import { calculateDateRanges, formatChartDate, getCachedData, setCachedData } from './google.api.utils';
10
+ // Migration-time debug flag (owner requested): verbose cache traces during migration
11
+ const debug = false; // keep as literal during migration for traceability
10
12
  /**
11
13
  * Create authenticated Google API client for a specific service
12
14
  */
@@ -71,7 +73,7 @@ export async function createSearchConsoleClient(config) {
71
73
  };
72
74
  }
73
75
  // Cache for analytics data (1 hour)
74
- const analyticsCache = new RouteCache();
76
+ const analyticsCache = new CacheManager({ prefix: 'sitehealth-analytics-', ttl: 60 * 60 * 1000 });
75
77
  /**
76
78
  * Get Google Analytics data for a site with current/previous period comparison
77
79
  */
@@ -81,8 +83,12 @@ export async function getGoogleAnalyticsData(config, siteName, startDate, endDat
81
83
  const cacheKey = `analytics-${siteName}-${startDate || 'default'}-${endDate || 'default'}`;
82
84
  const cached = getCachedData(analyticsCache, cacheKey);
83
85
  if (cached) {
86
+ if (debug)
87
+ console.debug('[site-health][analytics] cache HIT', cacheKey);
84
88
  return { success: true, data: cached };
85
89
  }
90
+ if (debug)
91
+ console.debug('[site-health][analytics] cache MISS', cacheKey);
86
92
  if (!config.ga4PropertyId || config.ga4PropertyId === 'GA4_PROPERTY_ID_HERE') {
87
93
  return {
88
94
  success: false,
@@ -149,6 +155,8 @@ export async function getGoogleAnalyticsData(config, siteName, startDate, endDat
149
155
  });
150
156
  }
151
157
  // Cache the result
158
+ if (debug)
159
+ console.debug('[site-health][analytics] caching', cacheKey, 'rows=', chartData.length);
152
160
  setCachedData(analyticsCache, cacheKey, chartData);
153
161
  return { success: true, data: chartData };
154
162
  }
@@ -161,7 +169,7 @@ export async function getGoogleAnalyticsData(config, siteName, startDate, endDat
161
169
  }
162
170
  }
163
171
  // Cache for search console data (1 hour)
164
- const searchConsoleCache = new RouteCache();
172
+ const searchConsoleCache = new CacheManager({ prefix: 'sitehealth-searchconsole-', ttl: 60 * 60 * 1000 });
165
173
  /**
166
174
  * Get Google Search Console data for a site with current/previous period comparison
167
175
  */
@@ -245,6 +253,8 @@ export async function getSearchConsoleData(config, siteName, startDate, endDate)
245
253
  });
246
254
  }
247
255
  // Cache the result
256
+ if (debug)
257
+ console.debug('[site-health][searchconsole] caching', cacheKey, 'rows=', chartData.length);
248
258
  setCachedData(searchConsoleCache, cacheKey, chartData);
249
259
  return { success: true, data: chartData };
250
260
  }
@@ -188,16 +188,6 @@
188
188
  "scoreLogic": "present",
189
189
  "displayTemplate": "{{count}} robots meta tag(s) found"
190
190
  },
191
- "hreflang-tags": {
192
- "id": "hreflang-tags",
193
- "title": "Hreflang Tags",
194
- "description": "Checks for hreflang link tags for international SEO",
195
- "scoreDisplayMode": "binary",
196
- "pattern": "<link[^>]*rel=[\"']alternate[\"'][^>]*hreflang=[\"'][^\"']*[\"'][^>]*>",
197
- "countLogic": "count",
198
- "scoreLogic": "present",
199
- "displayTemplate": "{{count}} hreflang link(s) found"
200
- },
201
191
  "indexability-status": {
202
192
  "id": "indexability-status",
203
193
  "title": "Indexability Status",
@@ -4,10 +4,11 @@
4
4
  */
5
5
  "use server";
6
6
  import { CloudWatchClient, GetMetricDataCommand } from '@aws-sdk/client-cloudwatch';
7
- import { RouteCache } from './site-health-cache';
7
+ import { CacheManager } from '../../general/cache-manager';
8
8
  import { getFullPixelatedConfig } from '../../config/config';
9
+ const debug = false; // migration-time verbose logging
9
10
  // Cache for health check data (15 minutes)
10
- const healthCheckCache = new RouteCache(15 * 60 * 1000);
11
+ const healthCheckCache = new CacheManager({ prefix: 'sitehealth-cloudwatch-', ttl: 15 * 60 * 1000 });
11
12
  /**
12
13
  * Get health check data for a site using CloudWatch metrics
13
14
  */
@@ -17,7 +18,11 @@ export async function getCloudwatchHealthCheckData(config, siteName, startDate,
17
18
  const cacheKey = `cloudwatch-${siteName}-${config.healthCheckId}-${startDate || 'default'}-${endDate || 'default'}`;
18
19
  const cached = healthCheckCache.get(cacheKey);
19
20
  if (cached) {
20
- return { success: true, data: cached };
21
+ if (Array.isArray(cached)) {
22
+ return { success: true, data: cached };
23
+ }
24
+ // defensive: cached value present but not an array — coerce to empty array
25
+ return { success: true, data: [] };
21
26
  }
22
27
  // Use CloudWatch to get historical health check data
23
28
  // Prefer credentials from unified config (pixelated.config.json) when present (avoids env vars)
@@ -133,6 +138,8 @@ export async function getCloudwatchHealthCheckData(config, siteName, startDate,
133
138
  filledData = data;
134
139
  }
135
140
  // Cache the result
141
+ if (debug)
142
+ console.debug('[site-health][cloudwatch] caching', cacheKey, 'rows=', filledData.length);
136
143
  healthCheckCache.set(cacheKey, filledData);
137
144
  return { success: true, data: filledData };
138
145
  }
@@ -1,6 +1,6 @@
1
1
  import { Route53Client, GetHealthCheckStatusCommand } from '@aws-sdk/client-route-53';
2
2
  import { getFullPixelatedConfig } from '../../config/config';
3
- const debug = true;
3
+ const debug = false;
4
4
  export async function checkUptimeHealth(healthCheckId) {
5
5
  try {
6
6
  // Simple Route 53 call (global service). Prefer credentials from pixelated.config.json when present
@@ -17,8 +17,8 @@
17
17
  .accordion-title {
18
18
  cursor: pointer;
19
19
  padding: 1rem;
20
- font-size: 1rem;
21
- font-weight: 600;
20
+ /* font-size: 1rem;
21
+ font-weight: 600; */
22
22
  color: #1a202c;
23
23
  background: none;
24
24
  border: none;
@@ -62,8 +62,8 @@ details[open] .accordion-title::before {
62
62
 
63
63
  .accordion-title h3 {
64
64
  margin: 0;
65
- font-size: inherit;
66
- font-weight: inherit;
65
+ /* font-size: inherit;
66
+ font-weight: inherit; */
67
67
  color: inherit;
68
68
  flex: 1;
69
69
  }
@@ -10,7 +10,8 @@ const categoryIcons = {
10
10
  'Content & Management': '📝',
11
11
  'Support & Maintenance': '🛠️',
12
12
  'Ownership & Legal': '📋',
13
- 'Services': '💼'
13
+ 'Services': '💼',
14
+ '': ''
14
15
  };
15
16
  FAQAccordion.propTypes = {
16
17
  faqsData: PropTypes.shape({
@@ -55,7 +56,8 @@ export function FAQAccordion({ faqsData }) {
55
56
  const accordionItems = filteredFaqs.map((faq, index) => {
56
57
  const content = Array.isArray(faq.acceptedAnswer.text) ? (_jsx("div", { children: faq.acceptedAnswer.text.map((paragraph, pIndex) => (_jsx("p", { dangerouslySetInnerHTML: { __html: paragraph } }, pIndex))) })) : (_jsx("div", { dangerouslySetInnerHTML: { __html: faq.acceptedAnswer.text } }));
57
58
  return {
58
- title: `${categoryIcons[faq.category] || '❓'} ${faq.name}`,
59
+ /* title: `${categoryIcons[faq.category as CategoryKey] || '❓'} ${faq.name}`, */
60
+ title: `${categoryIcons[faq.category] || ''} ${faq.name}`,
59
61
  content,
60
62
  open: expandedStates[index] || undefined
61
63
  };
@@ -35,6 +35,10 @@
35
35
  }
36
36
  }
37
37
 
38
+ .p-resume .p-skills div {
39
+ margin: 0 0 10px 0;
40
+ }
41
+
38
42
  /* http://microformats.org/wiki/h-resume */
39
43
 
40
44
  .p-resume {
@@ -53,6 +53,12 @@ export function generateUUID() {
53
53
  export function capitalize(str) {
54
54
  return str[0].toUpperCase() + str.toLowerCase().slice(1);
55
55
  }
56
+ /** Capitalize the first letter of each word in `input`. */
57
+ export function capitalizeWords(input) {
58
+ if (!input)
59
+ return input;
60
+ return input.replace(/\p{L}[\p{L}'’-]*/gu, (word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase());
61
+ }
56
62
  /*
57
63
  Array.prototype.contains = function(obj) {
58
64
  return this.indexOf(obj) > -1;
@@ -1 +1 @@
1
- pxl:v1:c70cbe09dc837373c6f97231:63d645cc86fe3d8ab9ed584e12567337:de5401e0f619e7bc50e6333ad1dce44aa01813cf21d55ad9a607b7492a46295e65915a988c3809c1cef0048c3a6a08d6ac73e35b951bfd442a4d8a0db29f0e004d244f7a01dfce7e92fc3b099f5d9f16cb1783ce383d9b4e20b4ec1dfe28761ccc1dde660d0e53be13c7adc4421b9ba775be16ad44368d4f45f821e9b03823c41a49434823e33a0b61e2886b85fa68f73bf2f1789e8096796d32438a116051d99e121795aae13365f27a68ea07f4261bb63ba5e3ce52033efc2a64d2681962bbe5ae76e5f0b1c265815ef651557727ec362c9fd0f92eeda070c1468578e0b30c23d764dd9ca0be56ffc28d61834702aa601dfb5df093d25f71e4255c9f34cae0f8a09512220468642249e477d53bfa1cd22b2c5b83fc5f995812bdf5f18056e87551e6f29f72a8c37fe119f3cf895cd88f4eda02c509a1ee469c48043a00f01e69320454262165aeb499c981cf765ecebc40a5a0b99d9dbd991e11fbc1a1c4140e1fa21652edeaaa569e064bfe063e72521b4bb43d6603be1f1ead52536a52beeac985d91ab3b6e20b1d0e0bfefbe1a56340801736cf3a82fe6dc7b663d9cd70d68669894cc79ff0b992809a0910f7f2d42abfb86b64e4cf2e126a4ebab8976308ff61ea414cc33153c5feaf40f68cb7b61952f048761d75878cb57aeaf3a4ef04e754c560e268192749c6dc07b4488caafd5e1dcd09ac94523f7e9a0242a4ae85de3d045d98ba5a96af9d5068a8054728cd99f37cda73ccf8b46a5cb3978444e1e7d2a5b9a2ba90bb855c7e0ab9f13d78e9b234777109061565185775d369037c84505ab5bd224e91eea59ad32b64fd56d5451c9ac490c6cc479f4e6d76a02484a1aa9735979134a3b8b966817cd518e1d930d668f0f7fdfdda39e577bdb9a8332fd9dc1c60de418e51842965ab88d48469e6122c96e46a4302916a59cfae10957c91a7ac45f059fdb9429b993ac1705ab1a6fc43218f46c1b968fd00e41e11e7e2e4b7b69df78156cad91d30e7ab0d332fd99d1a6883d6a83d0cd713fa39cac6483ffef4f8603b8f9522d4f06968dd04eda944b152e056b173bed76609d1a9894bf6e35c1368f17e76ecc794792ed4b4444b924b6867599da45b208fe50ef540f99ac1fbe22b8ac4ceaee2ad069e96726c4740bb15fd12d50b9718cfed9a6eefc5db4bf86c78ab847d00043033f9991dc978ca5c5f1555e77ef04ff00d83da505bc8141ae1539b0e1dd3f42730fee6ba5d6fc02788df8a0489ba4f1b2542f6fd87b76c2bbb93330c165230d7c767bd51387ec8730bae8d435187da55cfb1deb10be60a80be7d29aa27772b2ecbb4340c0901574c8fee44d2c23b4c9d5f012671a260ad62dde2f1f95d6d6892c90a5fd57b20f3c36e10ad28083981685aea41774f828f5b379a0ae5041ea0d29aebf09e62f0ffaa789b3e6616270a3f6e74a5edd7ed18716f157af8af96c959021ba8553be53db638e3663c21a40d4932702163dbfd5834fb4a7f113bdc4d29346b7238e4461324ed2b614ee4a6e434d1207a824864aea955b24090f8e82320b395dc724defa313b3711ca8dedb1ede348367c8879a5c46aaa90bb57581b7643012fa19ca0c6d8956d4c8b8b50b1a077d4c3e3f5ee802084939b5c7a0c9113bcc06d787411d0c3e4a9f8177f0ec89bba4d0d7ff0a30751daadf6e762ac910f0298e4d3ca0d278f27dfaf16ec0d13533aeab259aa3f896f5018b4fd6b7a8b8b4002c3008e4cf8fb7f550e228579cb459c167095da7eb1930a1504325ad30b08de63df8854f7b47becf4e82d19629ba5ee2ae0a43d74f4af216b38db702b4d7325abc47dc9e9ead359f5f892dee204ec12a4dba509c2fe4892d2fe6fcac1911116fd01a5901af1c60b107ae53a588fb2bfadfa88fdcf2b7ddbd14c4d658ad2b580004cf888379c3339a95e93b7e03c41068b6b2c27c8bc29cf8c075f794f33ee5cff0ad08320c06c28b43308015c3ec4084062714aee486db9e0aa492637917f8a68d544515ec38546f9535f24d4fe44190a4cd7b75a8986f789fa083975f031339af222e6ad84da67d633c4afc7bfcc88c01ba16dc3d9f81952ebd4f2e940d427213fbe7628d1fb53c280c14599cfc6fa500e67abd3a989a275c605c0f2993d15a21a887df3e1d508cc4e5089eb3f5ab9f8a0f8e6b04f9f630025adb8986367f14a2523ddd12e46a9baf761a161dd1e28037d701e7f452784ceaf6e804d021ff29ab1043c6d088fc2942c8fa8c66bcc0c76ba52c4ec527d3327f598992a30390d3dcefc64d626b4a60c5320a7e02f10e6d55a685153cf677d519e2c521c36e35a5f64dc3a4bd05fc5a4201e2f04354646b8e539723eaaf112899f0d9b34a1b3370e6e65a41b474503d85f1052064430939732e7b1212df608011d9e220965ab48c7c4925f81437d7d3c93995f0d6f9f92ec74d4faf4ffdf3a25c8eb4df5140e1afa3f5409edf52eb2a2c14e0b65d9d0ccf9f3c435fcd51676d0db022705a517a732634b2869e01ad3a2669aa84c9ced95dbba2203bc0134944b568a0d9dce086b7dfbd11b4066e2572d1d4c00854cd476fcb27a7b8dd262ba9da2de4da1db90f47ad3053967e24de047fde2e7dbd8933176cf47b2cd51297d5aafbbfd801b71df15768d159a69556acf580f012b6230891b6b5fd61c9c80ef7f7a76a12b4018cad6e2d419b072e9622811253cfa73cc780a310cedd439797bf2aceb7d9855c8ad06e6e2b7daacc0c93d89cdc265b27d8d46d1101ba1518bfad0d5dc869b0c1d8879ee8ba85ff41aae3adb7a3a4c85b939b15591b022ffa43b89ec305668f755a230e59362007a035421f4ddd0b1ee4a4d4f18db66d758a9bfb8d26610f0e340153d551dfc11c48ae816de02e2aaae4d4b2b6a2aaa2c5c11d4d2ef5410bd0b230c8e9d0bacce1906fffdb0e28d5ccdfb54682845bbe59906d3e50b896f888a5eb91120c1192046228a27e9e8a13d525c7d1df963d947a71bb95cd07a4526bf61c8b3986e8963871e94bc8e7db723cc9646fed49b5f823c601aa12dc2c61c2f4035e6a2f68793d31285f1d54b195b8a3126677ebcba699ba055beef1adae9c29213faf38a6e7cd889bb7ff37e6cda3e0ce5bc1274dd2b373da6fff9e9cae18e714b9a43698b1e3ebd31b3a2abd8bdcf500834b5aad1ec8220e1375b558cf53459b4f77d1746abfb6311c9b0f12035642bd307ca926622c07ab5b68487a41cb90f503303b33f828c48dabc4076b0a72e4aee69e367e4a8e145ad5955afa4a901ba32acd46f75b7f7cf9f9e8f0557a5687f8097ca8f0af694cee2f2adff0d31683c0526f99c29e6bf54c62f71f61315b566fd9aa15131722e07a27b014632a82b9f6746ab8c9e2826d37056aff5658303f0c6e5d3a08616a3c49be7ddc1f6b7e0f2bed7a9d17b5fdbc9e99aae9e3ccf683da49b5123ea90cc25887751c2bbc3b931b0fa2891cbd2619aad145898a71105e393284311f39a642570540c7d8936e0284c269b178f1aca07a7d378caeabb7273ac2b114120caf05080d27485f11515313561b4b7cc573da43745b623b56ac4facaa6e970f2f191422ba45d12744754d290034694b2f7eb950c225e0b53907ea68985e3b2c27eaba4ecf774a24aba842826d73c2fc5b1e2671c80a392bbe72c45c0bdca3e62d3a87fddf6684187b577e9d3da21833747e6d25d15b06e035d892acf1242e4a739e844c9b1a62592ba83eaacdcef19cbeda4c9f5fa152a8219f735b8c3d43553b799fbedf1013883f9aee7b3069650f53b117790261d2b48e1fe289061aaca736dbaa8118a836b5b1045bfe4e2707829ee2d9fb978814f79fd2be61f36c3d490e149201731fc3c38685de1620306340a5259d62550560c9e36f1b60c0264b5a64e865f5cf21756fdda21270111d02e13947a651b14056296d268c1b9b89edfc983233541797a70c7831a361b94d830c96f02765ed2bd27cb15c4f06228d723db97c61ef679074960db5bcd533d88485589224412cbd02676d63a70588c4d864c9eb20703d8413749d4ec2195a118524ff63097750c68e991b6a53971ced2ad22d22c13300af131a8133b64c68095e4f4a52689a9368d339e0ec0b769f0a83e7002fa02ad4c954499680fd93c42d0e8aa7864eac7bad8aea8c560815ba620e55f6157b20e937db6d02a6abc3f04588c07e1f02445a0c01230316def1f7f4fb7bedecf8d49034dcb27aeabf3a733e8c02160ef1a91909edc20a49266a38eae88e83f66a6809a0a9edefc8feeba2bced621cbba28a3a400df83f152292e3a9ad0074599a90387fbd67bbe9a9c64611176ee81623283839e3959304b5addca8e5875b32f84a0b446bbbe391c323c41f7aeee5a992419da68f5fd47da1b3a227c8532eebe46fd3491f02ea9e11ab4932a74a0770800301c311afb2af8918511fe6d2051a4af053e34629543e23870b064173b0b8bde9ef6745b62b6f6ff9f6a54d138ff3fcc6fd710d3f136a3780269d2d92babd145319aa64e441c516426640dfde81d70a07f24c8956d512a9db47c1d3d928d56bf183206b8f67f2fb91dba8bab52f23e477db35d633e5a63e22daa78b33d28dcceb7820bb43ec99cc8a1a30164c5a0a090bc2065df37f184ab3075618917222cc4f2bbf8680e881507124b5f0b7460a1a590ee142d9fd4097cd9bd375cf4f14b9b7b21243456752f100e07d25818e7e7383637fc6c96ecd60c91ac6bd8ad82b3efcf60ad0f874ae681f896ea249478e1fc1eda90417d7352bad6b06a67cfa70a0b2d6f5063da403c182eebd05896e20e4dd13f409f34a6afc8c378bb42966c0ade4368275feb11b642d5038e8cf01a9738bd09f10a49fb4daf9d84bdcf5703bf575125369b15e59a980511187a9a5365fe5aa43fd68a012d673f6899e919d0e7ef5223bd594c1b0035ed1bed609f2e38e46e8311b58b9706c7dbeec8e0d3887e6f5dfb611df3ee8a67a122cda70d8dbf5dcf299048c85408d32765c0fb9fd2febb8c1d067f6d2fe8d82ce499197943f22d375f8cc4c5546a23136b08bc90b288abea36e22b87e8bd37bf3aa9dbeb1f643da7a42fb01a245a892db4ae375365d3eda2a0ffe83fe953d0cdfbfd46a6869dd13b5953d4343c452f0f66b2825cb6a819e586fd53ea7c3b8dc7a8bf2e09c28747e7e9883be9a50ae
1
+ pxl:v1:3e3b3b2f37db000bc900016a:eccf9d997d641ae455d0d6966b1d3eee:8b2d37b2b7c74f499c58dcd7edbf0ef2c8df5161f9bec74000f6f28ff33ae0f0d2324f24f06600185bfafe3610e27d32182ba2b8c6bb47202f9cfdb3ee29a96154e7613de886588b8dd76b998c73755358174e0f2a095eadd91003e139a90b5fb6cd009da65d10a4b235f247a396dcbe1c01af5210f0f6e9ecee80b52d9441378d387453fbbd70580cc2701e794e213bf6f52ced2f886c431ff41d76b3e4858abc0da2da144f86367c5d07f8a94a88273b9ed807a2d887a607a419cd6082e0dd7978450300d72095772305e1419d4ddfd3df46c7e3d82a7753ce22411c56d7ef761e7eb88bfd6b8edb5b88838ea75a991e242ee63e98de176cc8f1da9a5bdaa5bb9f2935d07f08e36d0e41702df58b49306f70630365f54ec569d033ae7e4bf13de4d50c3762f18f8ec5f8dbb7066cc56271f714a104a9ce19486e44fc329256893fdafa38a18f3aeb7fcd83ef31c247cb2072f66cfca1656396bbebad2826fb612ff8f99511a03672e282a60e6e300b3f4b7cb869534d4d8b7330531d2c1ed4ded7922e05ed39f2f166bc083f930ba5e2fb8f51d77bd433c95810ac6768ac2cdc2043812477a56432febca7b3d04ae73151b2d3d06bc66c21687c0c88cef4f886806c14f85b4b30d87a4e295cd6cee27ac7b8ad80fa70513accb8b5cd786d32713ceb12209515fa4078afd6c8c0a98739ad30428e662199cb4f618263cf94389be769570e562c631537ffe2f71a694026e7d45ed0dd4cb6762ad1b35209db6bfa06bbef0ab783181b12d3cd48f965edd907bf26747feea7b8445466382082e6dcf745fd5dfd5e574875e9b6fd5a52d17003445edcfb27c81cfba29a8e54c0cbc0c036d09a13b444002d49502251cd27865a14dc25a2b6c3bd766f9da8eb8a50f448ddf10cc926c9d42161c55811fa0c349d75df05122f3753b2c2be707f0d1c7515fdf586af24ee8ed9ce7dce9909e96e59f7576e504f50bd7ef971ac9f8d134130273a21ac74219010dbb5511050cffd9416020a9f9b2bb53144f8f328535d93b2fe5b3c9be1864daf80ae288d70a46b909e3fb8f1762b77c50e79de7f3b936647d5a392203ae87a6f13e57160cc526aa186e01800b282e57e6f5e06fc96560e16928aa640a1233b848caaadd7bfc266e4136773d348e2b74ba835d6a429abade5421a7be9278a8b9e1a41e6a2146d67bc60a04fb40bc90d61edefd3ca68ee91fd7179eb0513c30e81596f4bdaaf70aa179c90cf12e6aa72a90257395deeae0345eca67c1fa44b9db56580272000cd63079079547527bedf5cd91a02f1ec15e33b93b9988b92cbae1163c989731e82822653ed84c457cab76e85c87e77699a2be93bbfe46b74d66c8447a3d26a64b9b6e140320d7b131171d76de75ae8acbf2744d5d00ad7a017751984cc2bcfe6bd1872285819f35cb0e26c61538f50b2db653be9867f5d0f3f036231980f66f5936fdf3abb63b1d9a5cc51a9fa444554906bdb100e82594bd9f6599e4ed7253562df3fc58e8b44fc32fd81e0434bfff5d019b5145ea8b72276338b96d30ed5136df64137b885b304fccac2a6041c0ee02d1325d04e69882bb47405c20011a186a1f9e9018ae3bd0bd801e5ca33fe38032c325bb848f8fa67690cd4a894cf6b417ce3e5785f219cc98d1fd779392d250feea67882b90254e034541df5a49ed399aacb392f7df42e896f3cba7b901c6771340683168564072ae2731b1b7b28aa19a14faae93e7f20a917fab47e21b75a7c66f4ed439ca20231e21cd4139bc5332a7c359d7c685ef1bdca810168461f3d7e57c80349fb2ed74964a24352fa65d7f1e70cb05e688e8ae389a96f77c86e9c1968cd0c0cc8b7cb3253ad11ad55a91b79f01d60af5183fe402ebdb0e384d9c40e26afeef85c91fcba27c3c29cc6aeeaeebfc616514d95da6125885f38e9f4acf3f8c35ca00085d84b7d0f28df876edc3a9b19e553af2d23312d02fd56e19f0740832d52a344348a27744d9fb0b55a1d8a0a14c4a9e68d25ec09eb5202b7f5ca78c8ce5c42bcfbc05436b2d94ca564c76ba647aa8cbd03ffc6ca5b04e89b3226d2840988016265d84d71b41dae769644d711798935186cbee96b9e696b6480e5e7f011bfb24427d796dfbb4a256cb109e32481126a4330787cb4f94ab95b14b122eb7718e6fe732d9c1806e4a078dbcb84aa56a365233c05b59a2b947120e0654d4dd976b397d283c89f9c70270bf86c112da8e21dd4c42cb98e3355751b623304a3e07e7a5945bfdf9dafcff1d87534bf92f6dfe4672716dc285ba29245785b3944edc0d1a0a01887cdb74a5f8d924e1784cf0e9a641dc8dc3aa48b594f581c6718f486442fe46d2bf7682ead64ea8973912fcecb7c1cfcf02943c292b9ca3eec366b1f982494e51900e846ed3ed7c1b05acc01eb14a93e549c984830160a9de6d1f5e5cb44360235f1f5d2376798a7865f8826ac3ee899a9f30083d4f0cf1317bbeac55cf55e81e82808050ed99bec9c4c56c0b4c8ccaeddd93b9aa20ba5c613baf874fcef785ec97e2377bdb1022ee0b86ff3ddd6651fa34ae97ff8e69a62c4a40bff9cd34d8c344ae59d565f00f097eb417e3c020d8761db0f0a046f1acdb552db446c06272ac7882ac3abed2bb5a9b3dcebdcaf1e085f5d05b7bbfb25a2085b5e6e1418f1b95ab82ca744b0e31b917d4e7af73f4b55f6597944044bd55431e6475143483f7a0922e20137070c928d507678ccbc92ac94ce250ff585ebc45aab92d2a4cc36a97bcad85fb37c0f2bf8f1f9c95116bd2c12b473f23a234da3f5f8f130449a1ad55a2b5c4b293b913558ffb2e09a583853d23c557751b2fdbe6ac173d063663ee5d40096501d6653c53399dbb9df96dd829b8fb848ea24cc67b29f65063f3fc1e5bdba05e8b23e8e0b9b0dd8909535da7532dbbdb5428140098c8bb0a0a71a46545f85aa8dc511e6dd4abd23e283ddb7ec9fd9202ccad200a34d05c395a84cdee7f0273bdc8dbd6f5b546e6255c9e2216b0596c91068ec584700e1f1201f53888a525ea8e51df5e953a2cbd38bb83c8a21474ee05f1f8823688304c3a3c1bcd882fc8d74c357181b906c1ca4571236a3a8536fa3eddab9db0239a9aa6031c427ea3e0c50880fe8dae67e0e9440d695a00a831e8d1319de801cefa712b1fa6452bedde5c71206dee7fc2bdea2db0ea9820bed6a72dd0134976812058d712333994bfc1a5adad8a1e36e9a3eca4543d691f08846f0ca751611270b9f02c6590771962d8c3b939ce2caa07fe4d0cedb44ffa7e0345fefec7d384854b8bb061ca1970464c1e9ef4fc69216fe9084c45c672a15497bbb165964dc2692a7717cbc45cb0a8746db20ff6523ed2289b3470d98290a504d09e230d16683cdfd12c9a31dfa5e4417c13e2523e36371409a3438080b84887cd9a9d3cfc10f7a2359b6b84044ef34ae50144c2692be1d91b1b0d874b3a3c8e9ac0ade9ffde0488a7bffeec69fcd14fb5f32cd7bfcb24c0491b1f679383318dbf01bc0c1bec7945b116c2413c1cbdd44db41aa8eabcf794e25844aa6d942e59e9b7ff76e19d5a29b77760de72268b5c195583927dc54dedcc5097119d3a9c804455fab7eeaa5f7dea70cca406eabd11afca4a4a95acce2ea2d1f3d0bf9d57d0569c13010b2cda1fa1c9ed6d32547802301aedd803d4424ff9621515c7a0355a02953398b06119343ada45216a266ef1f7ff1e064b0e93117f750f885b1bc9055ed4456913f9f6f7ea9050aff8939fa86ca18366aa1324ac44427091f0f13e7e1e5198eb465872f9c0f14bc08253a6064631c3cfa1d8f2a11b0c13c1f46ec71db24c9b1e98c9ea50ed72971bc16005aafd5a05b372623b26aa2123bb585ad6a69bbde3d297d4458ecf000c2e96e89d1e09e0c47c7f1a92546720ad9c6da9d2f017ce1b28fe90f4919a30c2f92a1199bb0be0e8bb7c08c4cb0ee1e9f8671fb5b08c5421eb99ab870f631bd530436d17109d24299a0672c0c7c6b723a40e6fa115dde1645cd4edaecdc231a3cc40d7bb4108958e299ea3b9312c7cf9338479d9db93548cf2159068b137054dd2be73ca87dfb5868c10e444ed89a45588a43dae7292b82c2921b43afd50640d7bf70329b800ff30ceabb1de72eed1efd74648e09f49230c4913ea8e48c5e97317fb62cccf5252304c12f9ffacff79c49d879ba18ca2e614eb59b745a7a74fdeb1e2dd1181ec5679e7acce8e724ab60b89e496f3b925f2bbdde8248a2db00f71cbd9ba3dfd652d1aae6f361b5a07ec94ac3527d24fc225752c32aa5bfcdce9cc372f1dcb6e6372f8ee8872f74ca112a7a51b1df1142c1eec501a69e34217975cb026d4580d1ae54e153260ab12b8d207b3264d30f74435ed8f2133509058919fd4fe5bf29f8afe68250ecd7552a8dd03e56977579a117ec309da8a31a81fd083f557182ab9a777ec0594ed6d748d48179fd75564501b262e47900454fdfb6c664dd006bcfd250d64a405eb41786e2e9e220cbdb14dc83e48d27a590fa1515245d4b212ec03ada6f3acc6d119a7d4b702eaf54ede1f36ad066914e66173d3ab47fce9993d39df270428983aec047e727c1496c5619b85eb00a30ec3a24ad619ccbb23367f60e0c572ef0c2b6aa1b48a53e1500386c7c214d0458a40ba7ad467aef49939cae711f153eac93d9d97344b089c2eea45d6c5cb175c442356f12c0231938bff50e7552c7d40ec27a98f0c559426e689d6c5b20c549e2b5167117823eb1e7175bc981ae0a7f865f6cb6d1ee769db6541fc7b098b44ddc51c2a987c210b93755bacf4422d6a3f3cda5b37f0fcb955b063a257e512d0df1af3f41a6703fe6037d71148d0fe4555726e19fb1a5f76405c1c528c604c1cdadbadc7e3289813b6ab3313d1a345365dcea0a34962990ba5223af15e733067bfc75038d13dfeb7abe9ff9015c85decd248bd60a516927dcb15ea989d07c72e1c3ba363f90bae5f17e7f4b7b1014e7eea49cb200f49be4f88df7b733bec6709bf7d7ceacee13a4f55adc3f6ad15a9ed03f4d785980265443155b624c8f931a59f26c4351858f0af02b3472ef6cb3c269df8e6c627c5cbdb2164a0546493465d92313b7a748a2b32fc52aad73729ecfbcdced568c415cdf1a746c58be501e47796de60b556e701db3c3be83f8b77d3d2f26
@@ -21,7 +21,6 @@ export * from './components/admin/site-health/site-health-mock-context';
21
21
  // Client-safe admin components (can run on both client and server)
22
22
  export * from './components/admin/site-health/google.api.utils';
23
23
  export * from './components/admin/site-health/seo-constants';
24
- export * from './components/admin/site-health/site-health-cache';
25
24
  export * from './components/admin/site-health/site-health-indicators';
26
25
  export * from './components/admin/site-health/site-health-on-site-seo.integration';
27
26
  export * from './components/admin/site-health/site-health-performance';
@@ -5,11 +5,12 @@ export * from './components/admin/site-health/google.api.integration';
5
5
  export * from './components/admin/site-health/google.api.utils';
6
6
  export * from './components/admin/site-health/seo-constants';
7
7
  export * from './components/admin/site-health/site-health-axe-core.integration';
8
- export * from './components/admin/site-health/site-health-cache';
9
8
  export * from './components/admin/site-health/site-health-cloudwatch.integration';
10
9
  export * from './components/admin/site-health/site-health-core-web-vitals.integration';
11
10
  export * from './components/admin/site-health/site-health-github.integration';
12
11
  export * from './components/admin/site-health/site-health-google-analytics.integration';
12
+ // Re-export CacheManager for server/admin consumers (migration: RouteCache → CacheManager)
13
+ export * from './components/general/cache-manager';
13
14
  export * from './components/admin/site-health/site-health-google-search-console.integration';
14
15
  export * from './components/admin/site-health/site-health-indicators';
15
16
  export * from './components/admin/site-health/site-health-on-site-seo.integration';
@@ -428,8 +428,8 @@ const requiredFaqRule = {
428
428
  recommended: true,
429
429
  },
430
430
  messages: {
431
- missingFaqPage: 'FAQ page is missing. FAQ pages are strongly recommended for every site (src/app/faq/page.tsx).',
432
- missingFaqSchema: 'FAQSchema is missing from the FAQ page.',
431
+ missingFaqPage: 'FAQ page is missing. FAQ pages are strongly recommended (examples: src/app/faqs/page.tsx, src/app/(pages)/faqs/page.tsx, src/pages/faqs/index.tsx).',
432
+ missingFaqSchema: 'FAQSchema (SchemaFAQ / JSON-LD @type:FAQPage) is missing from the FAQ page.',
433
433
  },
434
434
  },
435
435
  create(context) {
@@ -437,27 +437,76 @@ const requiredFaqRule = {
437
437
  if (!context.getFilename().endsWith('layout.tsx')) return {};
438
438
 
439
439
  const projectRoot = context.cwd;
440
- const faqPath = path.join(projectRoot, 'src/app/faq/page.tsx');
440
+
441
+ function findFaqPath(root) {
442
+ // Walk `src/` and match any path segment or filename named `faq` or `faqs`.
443
+ // Return the first matching `page.*` / `index.*` or a direct faq(s).(ts|tsx|js|jsx) file.
444
+ // Returns `null` when no candidate is found.
445
+ const srcRoot = path.join(root, 'src');
446
+ if (!fs.existsSync(srcRoot)) return null;
447
+
448
+ const stack = [srcRoot];
449
+ const filePattern = /(^|\/)faqs?\.(t|j)sx?$/i; // matches .../faq.tsx, .../faqs.js, etc.
450
+ while (stack.length) {
451
+ const cur = stack.pop();
452
+ try {
453
+ const entries = fs.readdirSync(cur, { withFileTypes: true });
454
+ for (const e of entries) {
455
+ const full = path.join(cur, e.name);
456
+ const rel = path.relative(root, full).replace(/\\/g, '/');
457
+
458
+ if (e.isDirectory()) {
459
+ // directory named faq/faqs -> prefer page/index inside it
460
+ if (/^faqs?$/i.test(e.name)) {
461
+ const candidates = [
462
+ path.join(full, 'page.tsx'),
463
+ path.join(full, 'page.ts'),
464
+ path.join(full, 'index.tsx'),
465
+ path.join(full, 'index.ts'),
466
+ ];
467
+ for (const c of candidates) if (fs.existsSync(c)) return c;
468
+ }
469
+ // continue walking
470
+ stack.push(full);
471
+ continue;
472
+ }
473
+
474
+ // direct file matches like src/pages/faqs.tsx
475
+ if (filePattern.test(rel)) return full;
476
+ }
477
+ } catch (err) {
478
+ /* ignore unreadable dirs */
479
+ }
480
+ }
481
+
482
+ return null;
483
+ }
484
+
485
+ const faqPath = findFaqPath(projectRoot);
441
486
 
442
487
  return {
443
488
  'Program:exit'() {
444
- if (!fs.existsSync(faqPath)) {
489
+ // If finder returned nothing or the candidate does not exist -> missing page
490
+ if (!faqPath || !fs.existsSync(faqPath)) {
445
491
  context.report({
446
492
  loc: { line: 1, column: 0 },
447
493
  messageId: 'missingFaqPage',
448
494
  });
449
- } else {
450
- try {
451
- const content = fs.readFileSync(faqPath, 'utf8');
452
- if (!content.includes('FAQSchema')) {
453
- context.report({
454
- loc: { line: 1, column: 0 },
455
- messageId: 'missingFaqSchema',
456
- });
457
- }
458
- } catch (e) {
459
- // Ignore read errors
495
+ return;
496
+ }
497
+
498
+ // Accept component-based SchemaFAQ, `FAQSchema` identifier, or JSON-LD @type:FAQPage
499
+ try {
500
+ const content = fs.readFileSync(faqPath, 'utf8');
501
+ const hasSchema = /FAQSchema|SchemaFAQ|"@type"\s*:\s*"FAQPage"/i.test(content);
502
+ if (!hasSchema) {
503
+ context.report({
504
+ loc: { line: 1, column: 0 },
505
+ messageId: 'missingFaqSchema',
506
+ });
460
507
  }
508
+ } catch (e) {
509
+ // Ignore read errors
461
510
  }
462
511
  },
463
512
  };
@@ -1 +1 @@
1
- {"version":3,"file":"google.api.integration.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/google.api.integration.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"google.api.integration.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/google.api.integration.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"site-health-cloudwatch.integration.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-cloudwatch.integration.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,MAAM,WAAW,2BAA2B;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,6BAA6B;IAC7C,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAKD;;GAEG;AACH,wBAAsB,4BAA4B,CACjD,MAAM,EAAE,2BAA2B,EACnC,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,6BAA6B,CAAC,CAiJxC"}
1
+ {"version":3,"file":"site-health-cloudwatch.integration.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-cloudwatch.integration.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,MAAM,WAAW,2BAA2B;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,6BAA6B;IAC7C,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAKD;;GAEG;AACH,wBAAsB,4BAA4B,CACjD,MAAM,EAAE,2BAA2B,EACnC,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,6BAA6B,CAAC,CAsJxC"}
@@ -1 +1 @@
1
- {"version":3,"file":"faq-accordion.d.ts","sourceRoot":"","sources":["../../../../src/components/general/faq-accordion.tsx"],"names":[],"mappings":"AACA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,qBAAqB,CAAC;AA8B7B,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;AACzE,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE,gBAAgB,2CAsF1D;yBAtFe,YAAY"}
1
+ {"version":3,"file":"faq-accordion.d.ts","sourceRoot":"","sources":["../../../../src/components/general/faq-accordion.tsx"],"names":[],"mappings":"AACA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,qBAAqB,CAAC;AA+B7B,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;AACzE,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE,gBAAgB,2CAuF1D;yBAvFe,YAAY"}
@@ -6,6 +6,8 @@ export declare function randomBetween(min: number, max: number): number;
6
6
  export declare function generateKey(): string;
7
7
  export declare function generateUUID(): string;
8
8
  export declare function capitalize(str: string): string;
9
+ /** Capitalize the first letter of each word in `input`. */
10
+ export declare function capitalizeWords(input: string): string;
9
11
  export declare function attributeMap(oldAttribute: string): string;
10
12
  /**
11
13
  * Adds a single 'change' event listener to the document and uses event delegation
@@ -1 +1 @@
1
- {"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../../../src/components/general/utilities.ts"],"names":[],"mappings":"AAGA,wBAAgB,QAAQ,CAAE,GAAG,EAAE,MAAM,oBAUpC;AAGD,wBAAgB,SAAS,CAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;;EAmBxC;AAED,wBAAgB,aAAa,CAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,UAOtD;AAED,wBAAgB,WAAW,WAc1B;AAED,wBAAgB,YAAY,WAK3B;AAED,wBAAgB,UAAU,CAAE,GAAG,EAAE,MAAM,UAEtC;AAQD,wBAAgB,YAAY,CAAE,YAAY,EAAE,MAAM,UAgCjD;AAID;;;;OAII;AACJ,wBAAgB,YAAY,SAoB3B;AAOD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,UA0BhC,CAAC;AAGF;;GAEG;AACH,eAAO,MAAM,uBAAuB,UAQnC,CAAC;AAEF,eAAO,MAAM,wBAAwB,UAOpC,CAAC;AAGF;;GAEG;AACH,eAAO,MAAM,oBAAoB,UAoBhC,CAAC"}
1
+ {"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../../../src/components/general/utilities.ts"],"names":[],"mappings":"AAGA,wBAAgB,QAAQ,CAAE,GAAG,EAAE,MAAM,oBAUpC;AAGD,wBAAgB,SAAS,CAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;;EAmBxC;AAED,wBAAgB,aAAa,CAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,UAOtD;AAED,wBAAgB,WAAW,WAc1B;AAED,wBAAgB,YAAY,WAK3B;AAED,wBAAgB,UAAU,CAAE,GAAG,EAAE,MAAM,UAEtC;AAGD,2DAA2D;AAC3D,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKrD;AAQD,wBAAgB,YAAY,CAAE,YAAY,EAAE,MAAM,UAgCjD;AAID;;;;OAII;AACJ,wBAAgB,YAAY,SAoB3B;AAOD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,UA0BhC,CAAC;AAGF;;GAEG;AACH,eAAO,MAAM,uBAAuB,UAQnC,CAAC;AAEF,eAAO,MAAM,wBAAwB,UAOpC,CAAC;AAGF;;GAEG;AACH,eAAO,MAAM,oBAAoB,UAoBhC,CAAC"}
@@ -17,7 +17,6 @@ export * from "./components/admin/site-health/site-health-uptime";
17
17
  export * from "./components/admin/site-health/site-health-mock-context";
18
18
  export * from "./components/admin/site-health/google.api.utils";
19
19
  export * from "./components/admin/site-health/seo-constants";
20
- export * from "./components/admin/site-health/site-health-cache";
21
20
  export * from "./components/admin/site-health/site-health-indicators";
22
21
  export * from "./components/admin/site-health/site-health-on-site-seo.integration";
23
22
  export * from "./components/admin/site-health/site-health-performance";
@@ -5,11 +5,11 @@ export * from "./components/admin/site-health/google.api.integration";
5
5
  export * from "./components/admin/site-health/google.api.utils";
6
6
  export * from "./components/admin/site-health/seo-constants";
7
7
  export * from "./components/admin/site-health/site-health-axe-core.integration";
8
- export * from "./components/admin/site-health/site-health-cache";
9
8
  export * from "./components/admin/site-health/site-health-cloudwatch.integration";
10
9
  export * from "./components/admin/site-health/site-health-core-web-vitals.integration";
11
10
  export * from "./components/admin/site-health/site-health-github.integration";
12
11
  export * from "./components/admin/site-health/site-health-google-analytics.integration";
12
+ export * from "./components/general/cache-manager";
13
13
  export * from "./components/admin/site-health/site-health-google-search-console.integration";
14
14
  export * from "./components/admin/site-health/site-health-indicators";
15
15
  export * from "./components/admin/site-health/site-health-on-site-seo.integration";