@pixelated-tech/components 3.5.14 → 3.7.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 (358) hide show
  1. package/README.md +27 -0
  2. package/dist/components/admin/site-health/google.api.integration.js +258 -0
  3. package/dist/components/admin/site-health/google.api.utils.js +47 -0
  4. package/dist/components/admin/site-health/site-health-accessibility.js +4 -10
  5. package/dist/components/admin/site-health/site-health-axe-core.js +4 -10
  6. package/dist/components/admin/site-health/site-health-cloudwatch.js +24 -26
  7. package/dist/components/admin/site-health/site-health-dependency-vulnerabilities.js +4 -10
  8. package/dist/components/admin/site-health/site-health-github.js +8 -14
  9. package/dist/components/admin/site-health/site-health-google-analytics.integration.js +1 -107
  10. package/dist/components/admin/site-health/site-health-google-analytics.js +21 -29
  11. package/dist/components/admin/site-health/site-health-google-search-console.integration.js +1 -113
  12. package/dist/components/admin/site-health/site-health-google-search-console.js +22 -28
  13. package/dist/components/admin/site-health/site-health-mock-context.js +15 -0
  14. package/dist/components/admin/site-health/site-health-on-site-seo.js +10 -33
  15. package/dist/components/admin/site-health/site-health-overview.js +4 -10
  16. package/dist/components/admin/site-health/site-health-performance.js +4 -10
  17. package/dist/components/admin/site-health/site-health-security.js +6 -10
  18. package/dist/components/admin/site-health/site-health-seo.js +4 -10
  19. package/dist/components/admin/site-health/site-health-template.js +102 -44
  20. package/dist/components/admin/site-health/site-health-uptime.js +4 -9
  21. package/dist/components/admin/site-health/site-health.css +7 -0
  22. package/dist/components/{seo → general}/404.js +1 -1
  23. package/dist/components/{callout → general}/callout.js +1 -1
  24. package/dist/components/{carousel → general}/carousel.js +1 -1
  25. package/dist/components/{cms → general}/contentful.items.components.js +2 -2
  26. package/dist/components/{cms → general}/gravatar.components.js +1 -1
  27. package/dist/components/{cms → general}/instagram.components.js +2 -2
  28. package/dist/components/{structured → general}/markdown.js +1 -1
  29. package/dist/components/{structured → general}/recipe.js +1 -1
  30. package/dist/components/{structured → general}/resume.js +1 -1
  31. package/dist/components/general/semantic.js +1 -1
  32. package/dist/components/{seo → general}/sitemap.js +2 -2
  33. package/dist/components/{cms → general}/smartimage.js +1 -1
  34. package/dist/components/{structured → general}/socialcard.js +1 -1
  35. package/dist/components/general/table.js +1 -1
  36. package/dist/components/{carousel → general}/tiles.js +1 -1
  37. package/dist/components/{structured → general}/timeline.js +1 -1
  38. package/dist/components/{cms → general}/wordpress.components.js +2 -2
  39. package/dist/components/shoppingcart/ebay.components.js +3 -3
  40. package/dist/components/shoppingcart/ebay.functions.js +1 -1
  41. package/dist/components/shoppingcart/shoppingcart.components.js +2 -2
  42. package/dist/components/shoppingcart/shoppingcart.functions.js +1 -1
  43. package/dist/components/sitebuilder/page/lib/componentMap.js +1 -1
  44. package/dist/components/sitebuilder/page/lib/componentMetadata.js +1 -1
  45. package/dist/components/sitebuilder/page/lib/pageStorageContentful.js +2 -2
  46. package/dist/index.adminclient.js +3 -6
  47. package/dist/index.adminserver.js +7 -6
  48. package/dist/index.js +67 -73
  49. package/dist/index.server.js +19 -21
  50. package/dist/mocks/browser.js +1 -0
  51. package/dist/mocks/handlers.js +206 -0
  52. package/dist/mocks/index.js +1 -0
  53. package/dist/types/components/admin/site-health/google.api.integration.d.ts +82 -0
  54. package/dist/types/components/admin/site-health/google.api.integration.d.ts.map +1 -0
  55. package/dist/types/components/admin/site-health/google.api.utils.d.ts +32 -0
  56. package/dist/types/components/admin/site-health/google.api.utils.d.ts.map +1 -0
  57. package/dist/types/components/admin/site-health/site-health-accessibility.d.ts.map +1 -1
  58. package/dist/types/components/admin/site-health/site-health-axe-core.d.ts.map +1 -1
  59. package/dist/types/components/admin/site-health/site-health-cloudwatch.d.ts.map +1 -1
  60. package/dist/types/components/admin/site-health/site-health-dependency-vulnerabilities.d.ts.map +1 -1
  61. package/dist/types/components/admin/site-health/site-health-github.d.ts.map +1 -1
  62. package/dist/types/components/admin/site-health/site-health-google-analytics.d.ts.map +1 -1
  63. package/dist/types/components/admin/site-health/site-health-google-analytics.integration.d.ts +1 -21
  64. package/dist/types/components/admin/site-health/site-health-google-analytics.integration.d.ts.map +1 -1
  65. package/dist/types/components/admin/site-health/site-health-google-search-console.d.ts.map +1 -1
  66. package/dist/types/components/admin/site-health/site-health-google-search-console.integration.d.ts +1 -41
  67. package/dist/types/components/admin/site-health/site-health-google-search-console.integration.d.ts.map +1 -1
  68. package/dist/types/components/admin/site-health/site-health-mock-context.d.ts +18 -0
  69. package/dist/types/components/admin/site-health/site-health-mock-context.d.ts.map +1 -0
  70. package/dist/types/components/admin/site-health/site-health-on-site-seo.d.ts.map +1 -1
  71. package/dist/types/components/admin/site-health/site-health-overview.d.ts.map +1 -1
  72. package/dist/types/components/admin/site-health/site-health-performance.d.ts.map +1 -1
  73. package/dist/types/components/admin/site-health/site-health-security.d.ts.map +1 -1
  74. package/dist/types/components/admin/site-health/site-health-seo.d.ts.map +1 -1
  75. package/dist/types/components/admin/site-health/site-health-template.d.ts +9 -1
  76. package/dist/types/components/admin/site-health/site-health-template.d.ts.map +1 -1
  77. package/dist/types/components/admin/site-health/site-health-uptime.d.ts.map +1 -1
  78. package/dist/types/components/general/404.d.ts.map +1 -0
  79. package/dist/types/components/general/buzzwordbingo.d.ts.map +1 -0
  80. package/dist/types/components/general/buzzwordbingo.words.d.ts.map +1 -0
  81. package/dist/types/components/general/calendly.d.ts.map +1 -0
  82. package/dist/types/components/{callout → general}/callout.d.ts.map +1 -1
  83. package/dist/types/components/general/carousel.d.ts.map +1 -0
  84. package/dist/types/components/general/carousel.drag.d.ts.map +1 -0
  85. package/dist/types/components/general/cloudinary.d.ts.map +1 -0
  86. package/dist/types/components/general/contentful.delivery.d.ts.map +1 -0
  87. package/dist/types/components/general/contentful.items.components.d.ts.map +1 -0
  88. package/dist/types/components/general/contentful.management.d.ts.map +1 -0
  89. package/dist/types/components/general/faq-accordion.d.ts.map +1 -0
  90. package/dist/types/components/{cms → general}/flickr.d.ts +1 -1
  91. package/dist/types/components/general/flickr.d.ts.map +1 -0
  92. package/dist/types/components/general/google.reviews.components.d.ts.map +1 -0
  93. package/dist/types/components/general/google.reviews.functions.d.ts.map +1 -0
  94. package/dist/types/components/general/googleanalytics.d.ts.map +1 -0
  95. package/dist/types/components/general/googlemap.d.ts.map +1 -0
  96. package/dist/types/components/general/googlesearch.d.ts.map +1 -0
  97. package/dist/types/components/general/gravatar.components.d.ts.map +1 -0
  98. package/dist/types/components/general/gravatar.functions.d.ts.map +1 -0
  99. package/dist/types/components/general/hubspot.components.d.ts.map +1 -0
  100. package/dist/types/components/general/instagram.components.d.ts.map +1 -0
  101. package/dist/types/components/{cms → general}/instagram.functions.d.ts +1 -1
  102. package/dist/types/components/general/instagram.functions.d.ts.map +1 -0
  103. package/dist/types/components/general/manifest.d.ts.map +1 -0
  104. package/dist/types/components/general/markdown.d.ts.map +1 -0
  105. package/dist/types/components/general/menu-accordion.d.ts.map +1 -0
  106. package/dist/types/components/general/menu-expando.d.ts.map +1 -0
  107. package/dist/types/components/general/menu-simple.d.ts.map +1 -0
  108. package/dist/types/components/general/metadata.components.d.ts.map +1 -0
  109. package/dist/types/components/general/metadata.functions.d.ts.map +1 -0
  110. package/dist/types/components/general/nerdjoke.d.ts.map +1 -0
  111. package/dist/types/components/general/recipe.d.ts.map +1 -0
  112. package/dist/types/components/general/resume.d.ts.map +1 -0
  113. package/dist/types/components/general/schema-blogposting.d.ts.map +1 -0
  114. package/dist/types/components/{seo → general}/schema-blogposting.functions.d.ts +1 -1
  115. package/dist/types/components/general/schema-blogposting.functions.d.ts.map +1 -0
  116. package/dist/types/components/general/schema-faq.d.ts.map +1 -0
  117. package/dist/types/components/general/schema-localbusiness.d.ts.map +1 -0
  118. package/dist/types/components/general/schema-recipe.d.ts.map +1 -0
  119. package/dist/types/components/general/schema-services.d.ts.map +1 -0
  120. package/dist/types/components/general/schema-website.d.ts.map +1 -0
  121. package/dist/types/components/general/sitemap.d.ts.map +1 -0
  122. package/dist/types/components/general/smartimage.d.ts.map +1 -0
  123. package/dist/types/components/general/socialcard.d.ts.map +1 -0
  124. package/dist/types/components/general/tiles.d.ts.map +1 -0
  125. package/dist/types/components/general/timeline.d.ts.map +1 -0
  126. package/dist/types/components/general/wordpress.components.d.ts.map +1 -0
  127. package/dist/types/components/general/wordpress.functions.d.ts.map +1 -0
  128. package/dist/types/components/general/yelp.d.ts.map +1 -0
  129. package/dist/types/components/sitebuilder/page/lib/componentMap.d.ts +1 -1
  130. package/dist/types/components/sitebuilder/page/lib/pageStorageContentful.d.ts +1 -1
  131. package/dist/types/components/sitebuilder/page/lib/pageStorageContentful.d.ts.map +1 -1
  132. package/dist/types/index.adminclient.d.ts +3 -6
  133. package/dist/types/index.adminserver.d.ts +7 -6
  134. package/dist/types/index.d.ts +66 -72
  135. package/dist/types/index.server.d.ts +19 -19
  136. package/dist/types/mocks/browser.d.ts +1 -0
  137. package/dist/types/mocks/browser.d.ts.map +1 -0
  138. package/dist/types/mocks/handlers.d.ts +2 -0
  139. package/dist/types/mocks/handlers.d.ts.map +1 -0
  140. package/dist/types/mocks/index.d.ts +1 -0
  141. package/dist/types/mocks/index.d.ts.map +1 -0
  142. package/dist/types/stories/admin/site-health.mocks.d.ts +82 -0
  143. package/dist/types/stories/admin/site-health.mocks.d.ts.map +1 -0
  144. package/dist/types/stories/admin/site-health.stories.d.ts.map +1 -1
  145. package/dist/types/stories/callout/callout.stories.d.ts +1 -1
  146. package/dist/types/stories/carousel/carousel-hero.stories.d.ts +1 -1
  147. package/dist/types/stories/carousel/carousel-hero.stories.d.ts.map +1 -1
  148. package/dist/types/stories/carousel/carousel-reviews.stories.d.ts +1 -1
  149. package/dist/types/stories/carousel/carousel-reviews.stories.d.ts.map +1 -1
  150. package/dist/types/stories/carousel/carousel-workportfolio.stories.d.ts +1 -1
  151. package/dist/types/stories/carousel/carousel-workportfolio.stories.d.ts.map +1 -1
  152. package/dist/types/stories/carousel/carousel.stories.d.ts +1 -1
  153. package/dist/types/stories/carousel/carousel.stories.d.ts.map +1 -1
  154. package/dist/types/stories/carousel/tiles.stories.d.ts +1 -1
  155. package/dist/types/stories/carousel/tiles.stories.d.ts.map +1 -1
  156. package/dist/types/stories/cms/contentful.item.stories.d.ts +1 -1
  157. package/dist/types/stories/cms/contentful.item.stories.d.ts.map +1 -1
  158. package/dist/types/stories/cms/contentful.items.stories.d.ts +1 -1
  159. package/dist/types/stories/cms/contentful.items.stories.d.ts.map +1 -1
  160. package/dist/types/stories/cms/contentful.stories.d.ts +1 -1
  161. package/dist/types/stories/cms/contentful.stories.d.ts.map +1 -1
  162. package/dist/types/stories/cms/google.reviews.stories.d.ts +1 -1
  163. package/dist/types/stories/cms/google.reviews.stories.d.ts.map +1 -1
  164. package/dist/types/stories/cms/gravatar.stories.d.ts +1 -1
  165. package/dist/types/stories/cms/gravatar.stories.d.ts.map +1 -1
  166. package/dist/types/stories/cms/instagram.stories.d.ts +1 -1
  167. package/dist/types/stories/cms/instagram.stories.d.ts.map +1 -1
  168. package/dist/types/stories/cms/wordpress.stories.d.ts +1 -1
  169. package/dist/types/stories/cms/wordpress.stories.d.ts.map +1 -1
  170. package/dist/types/stories/general/smartimage.stories.d.ts +1 -1
  171. package/dist/types/stories/general/smartimage.stories.d.ts.map +1 -1
  172. package/dist/types/stories/menu/menu-accordion.stories.d.ts +1 -1
  173. package/dist/types/stories/menu/menu-accordion.stories.d.ts.map +1 -1
  174. package/dist/types/stories/menu/menu-expando.stories.d.ts +1 -1
  175. package/dist/types/stories/menu/menu-expando.stories.d.ts.map +1 -1
  176. package/dist/types/stories/menu/menu-simple.stories.d.ts +1 -1
  177. package/dist/types/stories/menu/menu-simple.stories.d.ts.map +1 -1
  178. package/dist/types/stories/nerdjoke.stories.d.ts +1 -1
  179. package/dist/types/stories/nerdjoke.stories.d.ts.map +1 -1
  180. package/dist/types/stories/seo/seo.404.stories.d.ts +1 -1
  181. package/dist/types/stories/seo/seo.404.stories.d.ts.map +1 -1
  182. package/dist/types/stories/seo/seo.faq-accordion.stories.d.ts +1 -1
  183. package/dist/types/stories/seo/seo.faq-accordion.stories.d.ts.map +1 -1
  184. package/dist/types/stories/seo/seo.googleanalytics.stories.d.ts +1 -1
  185. package/dist/types/stories/seo/seo.googleanalytics.stories.d.ts.map +1 -1
  186. package/dist/types/stories/seo/seo.googlesearch.stories.d.ts +1 -1
  187. package/dist/types/stories/seo/seo.googlesearch.stories.d.ts.map +1 -1
  188. package/dist/types/stories/seo/seo.metadata.stories.d.ts +1 -1
  189. package/dist/types/stories/seo/seo.metadata.stories.d.ts.map +1 -1
  190. package/dist/types/stories/seo/seo.schema.stories.d.ts +1 -1
  191. package/dist/types/stories/seo/seo.schema.stories.d.ts.map +1 -1
  192. package/dist/types/stories/seo/seo.sitemap.stories.d.ts +1 -1
  193. package/dist/types/stories/seo/seo.sitemap.stories.d.ts.map +1 -1
  194. package/dist/types/stories/structured/buzzword-bingo.stories.d.ts +2 -2
  195. package/dist/types/stories/structured/buzzword-bingo.stories.d.ts.map +1 -1
  196. package/dist/types/stories/structured/markdown.stories.d.ts +1 -1
  197. package/dist/types/stories/structured/markdown.stories.d.ts.map +1 -1
  198. package/dist/types/stories/structured/recipe.stories.d.ts +1 -1
  199. package/dist/types/stories/structured/recipe.stories.d.ts.map +1 -1
  200. package/dist/types/stories/structured/resume.stories.d.ts +1 -1
  201. package/dist/types/stories/structured/resume.stories.d.ts.map +1 -1
  202. package/dist/types/stories/structured/socialcard.stories.d.ts +1 -1
  203. package/dist/types/stories/structured/socialcard.stories.d.ts.map +1 -1
  204. package/dist/types/stories/structured/timeline.stories.d.ts +1 -1
  205. package/dist/types/stories/structured/timeline.stories.d.ts.map +1 -1
  206. package/dist/types/tests/google.api.integration.test.d.ts +2 -0
  207. package/dist/types/tests/google.api.integration.test.d.ts.map +1 -0
  208. package/dist/types/tests/google.api.utils.test.d.ts +5 -0
  209. package/dist/types/tests/google.api.utils.test.d.ts.map +1 -0
  210. package/package.json +10 -5
  211. package/dist/components/admin/site-health/google-api-auth.js +0 -69
  212. package/dist/types/components/admin/site-health/google-api-auth.d.ts +0 -37
  213. package/dist/types/components/admin/site-health/google-api-auth.d.ts.map +0 -1
  214. package/dist/types/components/carousel/carousel.d.ts.map +0 -1
  215. package/dist/types/components/carousel/carousel.drag.d.ts.map +0 -1
  216. package/dist/types/components/carousel/tiles.d.ts.map +0 -1
  217. package/dist/types/components/cms/calendly.d.ts.map +0 -1
  218. package/dist/types/components/cms/cloudinary.d.ts.map +0 -1
  219. package/dist/types/components/cms/contentful.delivery.d.ts.map +0 -1
  220. package/dist/types/components/cms/contentful.items.components.d.ts.map +0 -1
  221. package/dist/types/components/cms/contentful.management.d.ts.map +0 -1
  222. package/dist/types/components/cms/flickr.d.ts.map +0 -1
  223. package/dist/types/components/cms/google.reviews.components.d.ts.map +0 -1
  224. package/dist/types/components/cms/google.reviews.functions.d.ts.map +0 -1
  225. package/dist/types/components/cms/gravatar.components.d.ts.map +0 -1
  226. package/dist/types/components/cms/gravatar.functions.d.ts.map +0 -1
  227. package/dist/types/components/cms/hubspot.components.d.ts.map +0 -1
  228. package/dist/types/components/cms/instagram.components.d.ts.map +0 -1
  229. package/dist/types/components/cms/instagram.functions.d.ts.map +0 -1
  230. package/dist/types/components/cms/smartimage.d.ts.map +0 -1
  231. package/dist/types/components/cms/wordpress.components.d.ts.map +0 -1
  232. package/dist/types/components/cms/wordpress.functions.d.ts.map +0 -1
  233. package/dist/types/components/cms/yelp.d.ts.map +0 -1
  234. package/dist/types/components/menu/menu-accordion.d.ts.map +0 -1
  235. package/dist/types/components/menu/menu-expando.d.ts.map +0 -1
  236. package/dist/types/components/menu/menu-simple.d.ts.map +0 -1
  237. package/dist/types/components/nerdjoke/nerdjoke.d.ts.map +0 -1
  238. package/dist/types/components/seo/404.d.ts.map +0 -1
  239. package/dist/types/components/seo/faq-accordion.d.ts.map +0 -1
  240. package/dist/types/components/seo/googleanalytics.d.ts.map +0 -1
  241. package/dist/types/components/seo/googlemap.d.ts.map +0 -1
  242. package/dist/types/components/seo/googlesearch.d.ts.map +0 -1
  243. package/dist/types/components/seo/manifest.d.ts.map +0 -1
  244. package/dist/types/components/seo/metadata.components.d.ts.map +0 -1
  245. package/dist/types/components/seo/metadata.functions.d.ts.map +0 -1
  246. package/dist/types/components/seo/schema-blogposting.d.ts.map +0 -1
  247. package/dist/types/components/seo/schema-blogposting.functions.d.ts.map +0 -1
  248. package/dist/types/components/seo/schema-faq.d.ts.map +0 -1
  249. package/dist/types/components/seo/schema-localbusiness.d.ts.map +0 -1
  250. package/dist/types/components/seo/schema-recipe.d.ts.map +0 -1
  251. package/dist/types/components/seo/schema-services.d.ts.map +0 -1
  252. package/dist/types/components/seo/schema-website.d.ts.map +0 -1
  253. package/dist/types/components/seo/sitemap.d.ts.map +0 -1
  254. package/dist/types/components/structured/buzzwordbingo.d.ts.map +0 -1
  255. package/dist/types/components/structured/buzzwordbingo.words.d.ts.map +0 -1
  256. package/dist/types/components/structured/markdown.d.ts.map +0 -1
  257. package/dist/types/components/structured/recipe.d.ts.map +0 -1
  258. package/dist/types/components/structured/resume.d.ts.map +0 -1
  259. package/dist/types/components/structured/socialcard.d.ts.map +0 -1
  260. package/dist/types/components/structured/timeline.d.ts.map +0 -1
  261. /package/dist/components/{seo → general}/404.css +0 -0
  262. /package/dist/components/{structured → general}/buzzwordbingo.css +0 -0
  263. /package/dist/components/{structured → general}/buzzwordbingo.js +0 -0
  264. /package/dist/components/{structured → general}/buzzwordbingo.words.js +0 -0
  265. /package/dist/components/{cms → general}/calendly.js +0 -0
  266. /package/dist/components/{callout → general}/callout.scss +0 -0
  267. /package/dist/components/{carousel → general}/carousel.css +0 -0
  268. /package/dist/components/{carousel → general}/carousel.drag.js +0 -0
  269. /package/dist/components/{cms → general}/cloudinary.js +0 -0
  270. /package/dist/components/{cms → general}/contentful.delivery.js +0 -0
  271. /package/dist/components/{cms → general}/contentful.items.css +0 -0
  272. /package/dist/components/{cms → general}/contentful.management.js +0 -0
  273. /package/dist/components/{seo → general}/faq-accordion.css +0 -0
  274. /package/dist/components/{seo → general}/faq-accordion.js +0 -0
  275. /package/dist/components/{cms → general}/flickr.js +0 -0
  276. /package/dist/components/{cms → general}/google.reviews.components.js +0 -0
  277. /package/dist/components/{cms → general}/google.reviews.css +0 -0
  278. /package/dist/components/{cms → general}/google.reviews.functions.js +0 -0
  279. /package/dist/components/{seo → general}/googleanalytics.js +0 -0
  280. /package/dist/components/{seo → general}/googlemap.js +0 -0
  281. /package/dist/components/{seo → general}/googlesearch.css +0 -0
  282. /package/dist/components/{seo → general}/googlesearch.js +0 -0
  283. /package/dist/components/{cms → general}/gravatar.css +0 -0
  284. /package/dist/components/{cms → general}/gravatar.functions.js +0 -0
  285. /package/dist/components/{cms → general}/hubspot.components.js +0 -0
  286. /package/dist/components/{cms → general}/instagram.functions.js +0 -0
  287. /package/dist/components/{seo → general}/manifest.js +0 -0
  288. /package/dist/components/{structured → general}/markdown.css +0 -0
  289. /package/dist/components/{menu → general}/menu-accordion.css +0 -0
  290. /package/dist/components/{menu → general}/menu-accordion.js +0 -0
  291. /package/dist/components/{menu → general}/menu-expando.css +0 -0
  292. /package/dist/components/{menu → general}/menu-expando.js +0 -0
  293. /package/dist/components/{menu → general}/menu-simple.css +0 -0
  294. /package/dist/components/{menu → general}/menu-simple.js +0 -0
  295. /package/dist/components/{seo → general}/metadata.components.js +0 -0
  296. /package/dist/components/{seo → general}/metadata.functions.js +0 -0
  297. /package/dist/components/{nerdjoke → general}/nerdjoke.css +0 -0
  298. /package/dist/components/{nerdjoke → general}/nerdjoke.js +0 -0
  299. /package/dist/components/{structured → general}/recipe.css +0 -0
  300. /package/dist/components/{structured → general}/resume.css +0 -0
  301. /package/dist/components/{seo → general}/schema-blogposting.functions.js +0 -0
  302. /package/dist/components/{seo → general}/schema-blogposting.js +0 -0
  303. /package/dist/components/{seo → general}/schema-faq.js +0 -0
  304. /package/dist/components/{seo → general}/schema-localbusiness.js +0 -0
  305. /package/dist/components/{seo → general}/schema-recipe.js +0 -0
  306. /package/dist/components/{seo → general}/schema-services.js +0 -0
  307. /package/dist/components/{seo → general}/schema-website.js +0 -0
  308. /package/dist/components/{structured → general}/socialcard.css +0 -0
  309. /package/dist/components/{carousel → general}/tiles.css +0 -0
  310. /package/dist/components/{structured → general}/timeline.css +0 -0
  311. /package/dist/components/{cms → general}/wordpress.css +0 -0
  312. /package/dist/components/{cms → general}/wordpress.functions.js +0 -0
  313. /package/dist/components/{cms → general}/yelp.js +0 -0
  314. /package/dist/types/components/{seo → general}/404.d.ts +0 -0
  315. /package/dist/types/components/{structured → general}/buzzwordbingo.d.ts +0 -0
  316. /package/dist/types/components/{structured → general}/buzzwordbingo.words.d.ts +0 -0
  317. /package/dist/types/components/{cms → general}/calendly.d.ts +0 -0
  318. /package/dist/types/components/{callout → general}/callout.d.ts +0 -0
  319. /package/dist/types/components/{carousel → general}/carousel.d.ts +0 -0
  320. /package/dist/types/components/{carousel → general}/carousel.drag.d.ts +0 -0
  321. /package/dist/types/components/{cms → general}/cloudinary.d.ts +0 -0
  322. /package/dist/types/components/{cms → general}/contentful.delivery.d.ts +0 -0
  323. /package/dist/types/components/{cms → general}/contentful.items.components.d.ts +0 -0
  324. /package/dist/types/components/{cms → general}/contentful.management.d.ts +0 -0
  325. /package/dist/types/components/{seo → general}/faq-accordion.d.ts +0 -0
  326. /package/dist/types/components/{cms → general}/google.reviews.components.d.ts +0 -0
  327. /package/dist/types/components/{cms → general}/google.reviews.functions.d.ts +0 -0
  328. /package/dist/types/components/{seo → general}/googleanalytics.d.ts +0 -0
  329. /package/dist/types/components/{seo → general}/googlemap.d.ts +0 -0
  330. /package/dist/types/components/{seo → general}/googlesearch.d.ts +0 -0
  331. /package/dist/types/components/{cms → general}/gravatar.components.d.ts +0 -0
  332. /package/dist/types/components/{cms → general}/gravatar.functions.d.ts +0 -0
  333. /package/dist/types/components/{cms → general}/hubspot.components.d.ts +0 -0
  334. /package/dist/types/components/{cms → general}/instagram.components.d.ts +0 -0
  335. /package/dist/types/components/{seo → general}/manifest.d.ts +0 -0
  336. /package/dist/types/components/{structured → general}/markdown.d.ts +0 -0
  337. /package/dist/types/components/{menu → general}/menu-accordion.d.ts +0 -0
  338. /package/dist/types/components/{menu → general}/menu-expando.d.ts +0 -0
  339. /package/dist/types/components/{menu → general}/menu-simple.d.ts +0 -0
  340. /package/dist/types/components/{seo → general}/metadata.components.d.ts +0 -0
  341. /package/dist/types/components/{seo → general}/metadata.functions.d.ts +0 -0
  342. /package/dist/types/components/{nerdjoke → general}/nerdjoke.d.ts +0 -0
  343. /package/dist/types/components/{structured → general}/recipe.d.ts +0 -0
  344. /package/dist/types/components/{structured → general}/resume.d.ts +0 -0
  345. /package/dist/types/components/{seo → general}/schema-blogposting.d.ts +0 -0
  346. /package/dist/types/components/{seo → general}/schema-faq.d.ts +0 -0
  347. /package/dist/types/components/{seo → general}/schema-localbusiness.d.ts +0 -0
  348. /package/dist/types/components/{seo → general}/schema-recipe.d.ts +0 -0
  349. /package/dist/types/components/{seo → general}/schema-services.d.ts +0 -0
  350. /package/dist/types/components/{seo → general}/schema-website.d.ts +0 -0
  351. /package/dist/types/components/{seo → general}/sitemap.d.ts +0 -0
  352. /package/dist/types/components/{cms → general}/smartimage.d.ts +0 -0
  353. /package/dist/types/components/{structured → general}/socialcard.d.ts +0 -0
  354. /package/dist/types/components/{carousel → general}/tiles.d.ts +0 -0
  355. /package/dist/types/components/{structured → general}/timeline.d.ts +0 -0
  356. /package/dist/types/components/{cms → general}/wordpress.components.d.ts +0 -0
  357. /package/dist/types/components/{cms → general}/wordpress.functions.d.ts +0 -0
  358. /package/dist/types/components/{cms → general}/yelp.d.ts +0 -0
package/README.md CHANGED
@@ -115,6 +115,31 @@ npm install react react-dom prop-types
115
115
 
116
116
  This library is written in TypeScript and provides full type definitions. No additional setup required.
117
117
 
118
+ ### Release Process
119
+
120
+ This project uses an automated release script to ensure consistent versioning and branch synchronization:
121
+
122
+ ```bash
123
+ # Run the release script (must be on dev branch)
124
+ npm run release
125
+ # Or run directly:
126
+ ./scripts/release.sh
127
+ ```
128
+
129
+ The release script will:
130
+ - Update dependencies and run security audits
131
+ - Run linting and build the project
132
+ - Prompt for version bump type (patch/minor/major/custom/none)
133
+ - Commit changes with proper versioning
134
+ - Push dev branch to remote
135
+ - Force-sync main branch to match dev
136
+ - Create and push git tags
137
+ - **Optionally** publish to npm (with OTP authentication)
138
+
139
+ **Important**: Always run releases from the `dev` branch. The script ensures both `dev` and `main` branches stay synchronized.
140
+
141
+ **Universal Usage**: This script is designed to work with any Pixelated project and automatically detects project settings.
142
+
118
143
  ### Reference Implementation
119
144
 
120
145
  For a complete working example of Pixelated Components in action, check out the [pixelated-admin](https://github.com/brianwhaley/pixelated-admin) project. This admin interface demonstrates:
@@ -271,6 +296,8 @@ import { Accordion, Callout } from '@pixelated-tech/components';
271
296
 
272
297
  For detailed usage examples and API documentation, see the [Component Reference Guide](docs/components.md).
273
298
 
299
+ For administrative components and site management features, see the [Admin Components Guide](docs/admin.md).
300
+
274
301
  ### Storybook Interactive Demos
275
302
 
276
303
  Explore all components with live, interactive examples:
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Google API Integration Services
3
+ * Centralized integration for Google services (Analytics, Search Console, etc.)
4
+ * Combines authentication, caching, and data processing logic
5
+ */
6
+ "use server";
7
+ import { google } from 'googleapis';
8
+ import { RouteCache } from './site-health-cache';
9
+ import { calculateDateRanges, formatChartDate, getCachedData, setCachedData } from './google.api.utils';
10
+ /**
11
+ * Create authenticated Google API client for a specific service
12
+ */
13
+ export async function createGoogleAuthClient(config, scopes) {
14
+ try {
15
+ let auth;
16
+ if (config.serviceAccountKey) {
17
+ // Use service account authentication (recommended)
18
+ const credentials = JSON.parse(config.serviceAccountKey);
19
+ auth = new google.auth.GoogleAuth({
20
+ credentials,
21
+ scopes,
22
+ });
23
+ }
24
+ else if (config.clientId && config.clientSecret && config.refreshToken) {
25
+ // Fallback to OAuth2 (deprecated for server-side apps)
26
+ const oauth2Client = new google.auth.OAuth2(config.clientId, config.clientSecret);
27
+ oauth2Client.setCredentials({
28
+ refresh_token: config.refreshToken,
29
+ });
30
+ auth = oauth2Client;
31
+ }
32
+ else {
33
+ return {
34
+ success: false,
35
+ error: 'Google credentials not configured. Set GOOGLE_SERVICE_ACCOUNT_KEY or OAuth credentials.'
36
+ };
37
+ }
38
+ return { success: true, auth };
39
+ }
40
+ catch (error) {
41
+ return {
42
+ success: false,
43
+ error: `Authentication failed: ${error.message}`
44
+ };
45
+ }
46
+ }
47
+ /**
48
+ * Create Analytics Data API client
49
+ */
50
+ export async function createAnalyticsClient(config) {
51
+ const result = await createGoogleAuthClient(config, ['https://www.googleapis.com/auth/analytics.readonly']);
52
+ if (!result.success)
53
+ return result;
54
+ return {
55
+ success: true,
56
+ client: google.analyticsdata({ version: 'v1beta', auth: result.auth }),
57
+ auth: result.auth
58
+ };
59
+ }
60
+ /**
61
+ * Create Search Console API client
62
+ */
63
+ export async function createSearchConsoleClient(config) {
64
+ const result = await createGoogleAuthClient(config, ['https://www.googleapis.com/auth/webmasters.readonly']);
65
+ if (!result.success)
66
+ return result;
67
+ return {
68
+ success: true,
69
+ client: google.searchconsole({ version: 'v1', auth: result.auth }),
70
+ auth: result.auth
71
+ };
72
+ }
73
+ // Cache for analytics data (1 hour)
74
+ const analyticsCache = new RouteCache();
75
+ /**
76
+ * Get Google Analytics data for a site with current/previous period comparison
77
+ */
78
+ export async function getGoogleAnalyticsData(config, siteName, startDate, endDate) {
79
+ try {
80
+ // Check cache first
81
+ const cacheKey = `analytics-${siteName}-${startDate || 'default'}-${endDate || 'default'}`;
82
+ const cached = getCachedData(analyticsCache, cacheKey);
83
+ if (cached) {
84
+ return { success: true, data: cached };
85
+ }
86
+ if (!config.ga4PropertyId || config.ga4PropertyId === 'GA4_PROPERTY_ID_HERE') {
87
+ return {
88
+ success: false,
89
+ error: 'GA4 Property ID not configured for this site'
90
+ };
91
+ }
92
+ // Set up authentication
93
+ const authResult = await createAnalyticsClient(config);
94
+ if (!authResult.success) {
95
+ return {
96
+ success: false,
97
+ error: authResult.error || 'Authentication failed'
98
+ };
99
+ }
100
+ const analyticsData = authResult.client;
101
+ const dateRange = calculateDateRanges(startDate, endDate);
102
+ // Fetch current period data
103
+ const currentResponse = await analyticsData.properties.runReport({
104
+ property: `properties/${config.ga4PropertyId}`,
105
+ requestBody: {
106
+ dateRanges: [{ startDate: dateRange.currentStartStr, endDate: dateRange.currentEndStr }],
107
+ dimensions: [{ name: 'date' }],
108
+ metrics: [{ name: 'screenPageViews' }],
109
+ orderBys: [{ dimension: { dimensionName: 'date' } }],
110
+ },
111
+ });
112
+ // Fetch previous period data
113
+ const previousResponse = await analyticsData.properties.runReport({
114
+ property: `properties/${config.ga4PropertyId}`,
115
+ requestBody: {
116
+ dateRanges: [{ startDate: dateRange.previousStartStr, endDate: dateRange.previousEndStr }],
117
+ dimensions: [{ name: 'date' }],
118
+ metrics: [{ name: 'screenPageViews' }],
119
+ orderBys: [{ dimension: { dimensionName: 'date' } }],
120
+ },
121
+ });
122
+ // Create a map of previous period data by date
123
+ const previousDataMap = new Map();
124
+ previousResponse.data.rows?.forEach((row) => {
125
+ const dateStr = row.dimensionValues?.[0]?.value || '';
126
+ if (dateStr) {
127
+ previousDataMap.set(dateStr, parseInt(row.metricValues?.[0]?.value || '0'));
128
+ }
129
+ });
130
+ // Combine current and previous period data
131
+ const chartData = [];
132
+ const daysInRange = Math.ceil((dateRange.currentEnd.getTime() - dateRange.currentStart.getTime()) / (24 * 60 * 60 * 1000));
133
+ for (let i = daysInRange - 1; i >= 0; i--) {
134
+ const currentDate = new Date(dateRange.currentEnd);
135
+ currentDate.setDate(currentDate.getDate() - i);
136
+ const currentDateStr = currentDate.toISOString().split('T')[0].replace(/-/g, ''); // YYYYMMDD format
137
+ // Calculate corresponding previous period date
138
+ const previousDate = new Date(currentDate.getTime() - (dateRange.currentEnd.getTime() - dateRange.currentStart.getTime()));
139
+ const previousDateStr = previousDate.toISOString().split('T')[0].replace(/-/g, ''); // YYYYMMDD format
140
+ // Get current period data
141
+ const currentRow = currentResponse.data.rows?.find((row) => row.dimensionValues?.[0]?.value === currentDateStr);
142
+ const currentPageViews = parseInt(currentRow?.metricValues?.[0]?.value || '0');
143
+ // Get previous period data
144
+ const previousPageViews = previousDataMap.get(previousDateStr) || 0;
145
+ chartData.push({
146
+ date: formatChartDate(currentDate),
147
+ currentPageViews: currentPageViews,
148
+ previousPageViews: previousPageViews,
149
+ });
150
+ }
151
+ // Cache the result
152
+ setCachedData(analyticsCache, cacheKey, chartData);
153
+ return { success: true, data: chartData };
154
+ }
155
+ catch (error) {
156
+ console.error('Google Analytics error:', error);
157
+ return {
158
+ success: false,
159
+ error: error.message
160
+ };
161
+ }
162
+ }
163
+ // Cache for search console data (1 hour)
164
+ const searchConsoleCache = new RouteCache();
165
+ /**
166
+ * Get Google Search Console data for a site with current/previous period comparison
167
+ */
168
+ export async function getSearchConsoleData(config, siteName, startDate, endDate) {
169
+ try {
170
+ // Check cache first
171
+ const cacheKey = `searchconsole-${siteName}-${startDate || 'default'}-${endDate || 'default'}`;
172
+ const cached = getCachedData(searchConsoleCache, cacheKey);
173
+ if (cached) {
174
+ return { success: true, data: cached };
175
+ }
176
+ if (!config.siteUrl) {
177
+ return {
178
+ success: false,
179
+ error: 'Site URL not configured for Search Console'
180
+ };
181
+ }
182
+ // Set up authentication
183
+ const authResult = await createSearchConsoleClient(config);
184
+ if (!authResult.success) {
185
+ return {
186
+ success: false,
187
+ error: authResult.error || 'Authentication failed'
188
+ };
189
+ }
190
+ const searchconsole = authResult.client;
191
+ const dateRange = calculateDateRanges(startDate, endDate);
192
+ // Fetch current period data
193
+ const currentResponse = await searchconsole.searchanalytics.query({
194
+ siteUrl: config.siteUrl,
195
+ requestBody: {
196
+ startDate: dateRange.currentStartStr,
197
+ endDate: dateRange.currentEndStr,
198
+ dimensions: ['date'],
199
+ rowLimit: 10000,
200
+ },
201
+ });
202
+ // Fetch previous period data
203
+ const previousResponse = await searchconsole.searchanalytics.query({
204
+ siteUrl: config.siteUrl,
205
+ requestBody: {
206
+ startDate: dateRange.previousStartStr,
207
+ endDate: dateRange.previousEndStr,
208
+ dimensions: ['date'],
209
+ rowLimit: 10000,
210
+ },
211
+ });
212
+ // Create a map of previous period data by date
213
+ const previousDataMap = new Map();
214
+ previousResponse.data.rows?.forEach((row) => {
215
+ const dateStr = row.keys?.[0] || '';
216
+ if (dateStr) {
217
+ previousDataMap.set(dateStr, {
218
+ clicks: parseFloat(String(row.clicks || '0')),
219
+ impressions: parseFloat(String(row.impressions || '0'))
220
+ });
221
+ }
222
+ });
223
+ // Combine current and previous period data
224
+ const chartData = [];
225
+ const daysInRange = Math.ceil((dateRange.currentEnd.getTime() - dateRange.currentStart.getTime()) / (24 * 60 * 60 * 1000));
226
+ for (let i = daysInRange - 1; i >= 0; i--) {
227
+ const currentDate = new Date(dateRange.currentEnd);
228
+ currentDate.setDate(currentDate.getDate() - i);
229
+ const currentDateStr = currentDate.toISOString().split('T')[0];
230
+ // Calculate corresponding previous period date
231
+ const previousDate = new Date(currentDate.getTime() - (dateRange.currentEnd.getTime() - dateRange.currentStart.getTime()));
232
+ const previousDateStr = previousDate.toISOString().split('T')[0];
233
+ // Get current period data
234
+ const currentRow = currentResponse.data.rows?.find((row) => row.keys?.[0] === currentDateStr);
235
+ const currentClicks = parseFloat(String(currentRow?.clicks || '0'));
236
+ const currentImpressions = parseFloat(String(currentRow?.impressions || '0'));
237
+ // Get previous period data
238
+ const previousData = previousDataMap.get(previousDateStr) || { clicks: 0, impressions: 0 };
239
+ chartData.push({
240
+ date: formatChartDate(currentDate),
241
+ currentImpressions: Math.round(currentImpressions),
242
+ currentClicks: Math.round(currentClicks),
243
+ previousImpressions: Math.round(previousData.impressions),
244
+ previousClicks: Math.round(previousData.clicks),
245
+ });
246
+ }
247
+ // Cache the result
248
+ setCachedData(searchConsoleCache, cacheKey, chartData);
249
+ return { success: true, data: chartData };
250
+ }
251
+ catch (error) {
252
+ console.error('Google Search Console error:', error);
253
+ return {
254
+ success: false,
255
+ error: error.message
256
+ };
257
+ }
258
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Google API Integration Utilities
3
+ * Shared utility functions for Google API integrations
4
+ * These are NOT server actions - just regular utility functions
5
+ */
6
+ /**
7
+ * Calculate date ranges for current and previous periods
8
+ */
9
+ export function calculateDateRanges(startDate, endDate) {
10
+ const currentEndDate = endDate ? new Date(endDate) : new Date();
11
+ const currentStartDate = startDate ? new Date(startDate) : new Date(currentEndDate.getTime() - 30 * 24 * 60 * 60 * 1000);
12
+ // Calculate previous period (same duration before the current period)
13
+ const periodDuration = currentEndDate.getTime() - currentStartDate.getTime();
14
+ const previousEndDate = new Date(currentStartDate.getTime() - 24 * 60 * 60 * 1000); // One day before start
15
+ const previousStartDate = new Date(previousEndDate.getTime() - periodDuration);
16
+ return {
17
+ currentStart: currentStartDate,
18
+ currentEnd: currentEndDate,
19
+ previousStart: previousStartDate,
20
+ previousEnd: previousEndDate,
21
+ currentStartStr: currentStartDate.toISOString().split('T')[0],
22
+ currentEndStr: currentEndDate.toISOString().split('T')[0],
23
+ previousStartStr: previousStartDate.toISOString().split('T')[0],
24
+ previousEndStr: previousEndDate.toISOString().split('T')[0],
25
+ };
26
+ }
27
+ /**
28
+ * Format date for chart display
29
+ */
30
+ export function formatChartDate(date) {
31
+ return date.toLocaleDateString('en-US', {
32
+ month: 'short',
33
+ day: 'numeric'
34
+ });
35
+ }
36
+ /**
37
+ * Get cached data or null if not cached
38
+ */
39
+ export function getCachedData(cache, cacheKey) {
40
+ return cache.get(cacheKey);
41
+ }
42
+ /**
43
+ * Set cached data
44
+ */
45
+ export function setCachedData(cache, cacheKey, data) {
46
+ cache.set(cacheKey, data);
47
+ }
@@ -1,6 +1,5 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useCallback } from 'react';
4
3
  import PropTypes from 'prop-types';
5
4
  import { SiteHealthTemplate } from './site-health-template';
6
5
  import { formatAuditItem, getAuditScoreIcon, getScoreColor } from './site-health-utils';
@@ -8,15 +7,10 @@ SiteHealthAccessibility.propTypes = {
8
7
  siteName: PropTypes.string.isRequired,
9
8
  };
10
9
  export function SiteHealthAccessibility({ siteName }) {
11
- const fetchAccessibilityData = useCallback(async (site) => {
12
- const response = await fetch(`/api/site-health/core-web-vitals?siteName=${encodeURIComponent(site)}`);
13
- const result = await response.json();
14
- if (!result.success) {
15
- throw new Error(result.error || 'Failed to fetch accessibility data');
16
- }
17
- return result;
18
- }, []);
19
- return (_jsx(SiteHealthTemplate, { siteName: siteName, title: "PageSpeed - Accessibility", fetchData: fetchAccessibilityData, children: (data) => {
10
+ return (_jsx(SiteHealthTemplate, { siteName: siteName, title: "PageSpeed - Accessibility", endpoint: {
11
+ endpoint: '/api/site-health/core-web-vitals',
12
+ responseTransformer: (result) => result, // Result is already in the correct format
13
+ }, children: (data) => {
20
14
  if (!data?.data || data.data.length === 0) {
21
15
  return (_jsx("p", { style: { color: '#6b7280' }, children: "No accessibility data available for this site." }));
22
16
  }
@@ -1,6 +1,5 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useCallback } from 'react';
4
3
  import PropTypes from 'prop-types';
5
4
  import { SiteHealthTemplate } from './site-health-template';
6
5
  import { getImpactIndicator, getIncompleteIndicator, getPassingIndicator } from './site-health-indicators';
@@ -8,14 +7,6 @@ SiteHealthAxeCore.propTypes = {
8
7
  siteName: PropTypes.string.isRequired,
9
8
  };
10
9
  export function SiteHealthAxeCore({ siteName }) {
11
- const fetchAxeCoreData = useCallback(async (site) => {
12
- const response = await fetch(`/api/site-health/axe-core?siteName=${encodeURIComponent(site)}`);
13
- const result = await response.json();
14
- if (!result.success) {
15
- throw new Error(result.error || 'Failed to fetch axe-core data');
16
- }
17
- return result;
18
- }, []);
19
10
  const getImpactColor = (impact) => {
20
11
  return getImpactIndicator(impact).color;
21
12
  };
@@ -34,7 +25,10 @@ export function SiteHealthAxeCore({ siteName }) {
34
25
  }
35
26
  return 'Unknown element';
36
27
  };
37
- return (_jsx(SiteHealthTemplate, { siteName: siteName, title: "Axe-Core Accessibility", fetchData: fetchAxeCoreData, children: (data) => {
28
+ return (_jsx(SiteHealthTemplate, { siteName: siteName, title: "Axe-Core Accessibility", endpoint: {
29
+ endpoint: '/api/site-health/axe-core',
30
+ responseTransformer: (result) => result, // Result is already in the correct format
31
+ }, children: (data) => {
38
32
  if (!data?.data || data.data.length === 0) {
39
33
  return (_jsx("p", { style: { color: '#6b7280' }, children: "No axe-core data available for this site." }));
40
34
  }
@@ -9,42 +9,40 @@ SiteHealthCloudwatch.propTypes = {
9
9
  endDate: PropTypes.string,
10
10
  };
11
11
  export function SiteHealthCloudwatch({ siteName, startDate, endDate }) {
12
- const fetchCloudwatchData = async (site) => {
13
- const params = new URLSearchParams({ siteName: site });
14
- if (startDate)
15
- params.append('startDate', startDate);
16
- if (endDate)
17
- params.append('endDate', endDate);
18
- const response = await fetch(`/api/site-health/cloudwatch?${params.toString()}`);
19
- if (!response.ok) {
20
- throw new Error(`Failed to fetch CloudWatch data: ${response.status}`);
21
- }
22
- const result = await response.json();
23
- if (!result.success) {
24
- if (result.error?.includes('Health Check ID not configured')) {
25
- throw new Error('Route53 Health Check ID not configured for this site');
26
- }
27
- else {
28
- throw new Error(result.error || 'Failed to load CloudWatch health check data');
29
- }
30
- }
31
- return result.data;
32
- };
33
- return (_jsx(SiteHealthTemplate, { siteName: siteName, title: "CloudWatch Uptime", columnSpan: 2, fetchData: fetchCloudwatchData, children: (data) => {
34
- if (!data || data.length === 0) {
12
+ return (_jsx(SiteHealthTemplate, { siteName: siteName, title: "CloudWatch Uptime", columnSpan: 2, endpoint: {
13
+ endpoint: '/api/site-health/cloudwatch',
14
+ params: {
15
+ ...(startDate && { startDate }),
16
+ ...(endDate && { endDate }),
17
+ },
18
+ responseTransformer: (result) => result.data, // Extract the data array from the response
19
+ }, children: (data) => {
20
+ // Ensure data is an array
21
+ if (!data || !Array.isArray(data) || data.length === 0) {
35
22
  return (_jsx("div", { className: "health-visualization-placeholder", children: _jsx("div", { className: "health-text-secondary", children: "No uptime data available. Route53 health checks may not be configured to send metrics to CloudWatch." }) }));
36
23
  }
37
24
  // Check if all data points have zero checks (no actual data)
38
- const hasActualData = data.some((point) => point.totalChecks > 0);
25
+ const hasActualData = data.some((point) => point && typeof point === 'object' && point.totalChecks > 0);
39
26
  if (!hasActualData) {
40
27
  return (_jsx("div", { className: "health-visualization-placeholder", children: _jsxs("div", { className: "health-text-secondary", children: ["Health check exists but has no metric data in CloudWatch for the selected period.", _jsx("br", {}), "Route53 health checks must be configured to send metrics to CloudWatch for historical data."] }) }));
41
28
  }
42
- return (_jsx("div", { children: _jsx("div", { style: { width: '100%', height: '400px', border: '1px solid #ddd' }, children: _jsx(ResponsiveContainer, { width: "100%", height: "100%", children: _jsxs(ComposedChart, { data: data, margin: { top: 40, right: 30, left: 20, bottom: 5 }, children: [_jsx("text", { x: "50%", y: 20, textAnchor: "middle", fontSize: "16", fontWeight: "bold", fill: "#374151", children: "CloudWatch Health Check Availability Over Time" }), _jsx(CartesianGrid, { strokeDasharray: "3 3" }), _jsx(XAxis, { dataKey: "date", tick: { fontSize: 12 }, angle: -45, textAnchor: "end", height: 60 }), _jsx(YAxis, { tick: { fontSize: 12 }, label: { value: 'Check Count', angle: -90, position: 'insideLeft' } }), _jsx(Tooltip, { formatter: (value, name) => [
29
+ // Filter out any invalid data points
30
+ const validData = data.filter((point) => point &&
31
+ typeof point === 'object' &&
32
+ typeof point.date === 'string' &&
33
+ typeof point.successCount === 'number' &&
34
+ typeof point.failureCount === 'number' &&
35
+ typeof point.totalChecks === 'number' &&
36
+ typeof point.successRate === 'number');
37
+ if (validData.length === 0) {
38
+ return (_jsx("div", { className: "health-visualization-placeholder", children: _jsx("div", { className: "health-text-secondary", children: "Invalid data format received from CloudWatch API." }) }));
39
+ }
40
+ return (_jsx("div", { children: _jsx("div", { style: { width: '100%', height: '400px', border: '1px solid #ddd' }, children: _jsx(ResponsiveContainer, { width: "100%", height: "100%", children: _jsxs(ComposedChart, { data: validData, margin: { top: 40, right: 30, left: 20, bottom: 5 }, children: [_jsx("text", { x: "50%", y: 20, textAnchor: "middle", fontSize: "16", fontWeight: "bold", fill: "#374151", children: "CloudWatch Health Check Availability Over Time" }), _jsx(CartesianGrid, { strokeDasharray: "3 3" }), _jsx(XAxis, { dataKey: "date", tick: { fontSize: 12 }, angle: -45, textAnchor: "end", height: 60 }), _jsx(YAxis, { tick: { fontSize: 12 }, label: { value: 'Check Count', angle: -90, position: 'insideLeft' } }), _jsx(Tooltip, { formatter: (value, name) => [
43
41
  value?.toLocaleString() || '0',
44
42
  name || 'Unknown'
45
43
  ], labelFormatter: (label) => `Date: ${label}` }), _jsx(Legend, { wrapperStyle: {
46
44
  fontSize: '12px',
47
45
  paddingTop: '10px'
48
- } }), _jsx(Bar, { dataKey: "successCount", stackId: "checks", fill: "#10b981", name: "Successful Checks", radius: [2, 2, 0, 0] }), _jsx(Bar, { dataKey: "failureCount", stackId: "checks", fill: "#ef4444", name: "Failed Checks", radius: [2, 2, 0, 0] })] }, `cloudwatch-chart-${data.length}`) }) }) }));
46
+ } }), _jsx(Bar, { dataKey: "successCount", stackId: "checks", fill: "#10b981", name: "Successful Checks", radius: [2, 2, 0, 0] }), _jsx(Bar, { dataKey: "failureCount", stackId: "checks", fill: "#ef4444", name: "Failed Checks", radius: [2, 2, 0, 0] })] }, `cloudwatch-chart-${validData.length}`) }) }) }));
49
47
  } }));
50
48
  }
@@ -1,21 +1,15 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useCallback } from 'react';
4
3
  import PropTypes from 'prop-types';
5
4
  import { SiteHealthTemplate } from './site-health-template';
6
5
  SiteHealthDependencyVulnerabilities.propTypes = {
7
6
  siteName: PropTypes.string.isRequired,
8
7
  };
9
8
  export function SiteHealthDependencyVulnerabilities({ siteName }) {
10
- const fetchDependencyData = useCallback(async (site) => {
11
- const response = await fetch(`/api/site-health/security?siteName=${encodeURIComponent(site)}`);
12
- const result = await response.json();
13
- if (!result.success) {
14
- throw new Error(result.error || 'Failed to fetch dependency data');
15
- }
16
- return result;
17
- }, []);
18
- return (_jsx(SiteHealthTemplate, { siteName: siteName, title: "Dependency Vulnerability", fetchData: fetchDependencyData, children: (data) => {
9
+ return (_jsx(SiteHealthTemplate, { siteName: siteName, title: "Dependency Vulnerability", endpoint: {
10
+ endpoint: '/api/site-health/security',
11
+ responseTransformer: (result) => result, // Result is already in the correct format
12
+ }, children: (data) => {
19
13
  if (!data) {
20
14
  return (_jsx("p", { style: { color: '#6b7280' }, children: "No dependency data available for this site." }));
21
15
  }
@@ -9,20 +9,14 @@ SiteHealthGit.propTypes = {
9
9
  endDate: PropTypes.string,
10
10
  };
11
11
  export function SiteHealthGit({ siteName, startDate, endDate }) {
12
- const fetchGitData = async (site) => {
13
- const params = new URLSearchParams({ siteName: encodeURIComponent(site) });
14
- if (startDate)
15
- params.append('startDate', startDate);
16
- if (endDate)
17
- params.append('endDate', endDate);
18
- const response = await fetch(`/api/site-health/github?${params.toString()}`);
19
- if (!response.ok) {
20
- throw new Error('Failed to fetch git data');
21
- }
22
- const data = await response.json();
23
- return data;
24
- };
25
- return (_jsx(SiteHealthTemplate, { siteName: siteName, title: "Git Push Notes", fetchData: fetchGitData, children: (data) => {
12
+ return (_jsx(SiteHealthTemplate, { siteName: siteName, title: "Git Push Notes", endpoint: {
13
+ endpoint: '/api/site-health/github',
14
+ params: {
15
+ ...(startDate && { startDate }),
16
+ ...(endDate && { endDate }),
17
+ },
18
+ responseTransformer: (result) => result, // Result is already in the correct format
19
+ }, children: (data) => {
26
20
  if (!data || !data.success) {
27
21
  return (_jsx("p", { style: { color: '#6b7280' }, children: "No git data available for this site." }));
28
22
  }
@@ -3,110 +3,4 @@
3
3
  * Server-side utilities for Google Analytics data retrieval
4
4
  */
5
5
  "use server";
6
- import { RouteCache } from './site-health-cache';
7
- import { createAnalyticsClient } from './google-api-auth';
8
- // Cache for analytics data (1 hour)
9
- const analyticsCache = new RouteCache();
10
- /**
11
- * Get Google Analytics data for a site with current/previous period comparison
12
- */
13
- export async function getGoogleAnalyticsData(config, siteName, startDate, endDate) {
14
- try {
15
- // Check cache first
16
- const cacheKey = `analytics-${siteName}-${startDate || 'default'}-${endDate || 'default'}`;
17
- const cached = analyticsCache.get(cacheKey);
18
- if (cached) {
19
- return { success: true, data: cached };
20
- }
21
- if (!config.ga4PropertyId || config.ga4PropertyId === 'GA4_PROPERTY_ID_HERE') {
22
- return {
23
- success: false,
24
- error: 'GA4 Property ID not configured for this site'
25
- };
26
- }
27
- // Set up authentication
28
- const authResult = await createAnalyticsClient(config);
29
- if (!authResult.success) {
30
- return {
31
- success: false,
32
- error: authResult.error || 'Authentication failed'
33
- };
34
- }
35
- const analyticsData = authResult.client;
36
- // Calculate date ranges
37
- const currentEndDate = endDate ? new Date(endDate) : new Date();
38
- const currentStartDate = startDate ? new Date(startDate) : new Date(currentEndDate.getTime() - 30 * 24 * 60 * 60 * 1000);
39
- // Calculate previous period (same duration before the current period)
40
- const periodDuration = currentEndDate.getTime() - currentStartDate.getTime();
41
- const previousEndDate = new Date(currentStartDate.getTime() - 24 * 60 * 60 * 1000); // One day before start
42
- const previousStartDate = new Date(previousEndDate.getTime() - periodDuration);
43
- const currentStartStr = currentStartDate.toISOString().split('T')[0];
44
- const currentEndStr = currentEndDate.toISOString().split('T')[0];
45
- const previousStartStr = previousStartDate.toISOString().split('T')[0];
46
- const previousEndStr = previousEndDate.toISOString().split('T')[0];
47
- // Fetch current period data
48
- const currentResponse = await analyticsData.properties.runReport({
49
- property: `properties/${config.ga4PropertyId}`,
50
- requestBody: {
51
- dateRanges: [{ startDate: currentStartStr, endDate: currentEndStr }],
52
- dimensions: [{ name: 'date' }],
53
- metrics: [{ name: 'screenPageViews' }],
54
- orderBys: [{ dimension: { dimensionName: 'date' } }],
55
- },
56
- });
57
- // Fetch previous period data
58
- const previousResponse = await analyticsData.properties.runReport({
59
- property: `properties/${config.ga4PropertyId}`,
60
- requestBody: {
61
- dateRanges: [{ startDate: previousStartStr, endDate: previousEndStr }],
62
- dimensions: [{ name: 'date' }],
63
- metrics: [{ name: 'screenPageViews' }],
64
- orderBys: [{ dimension: { dimensionName: 'date' } }],
65
- },
66
- });
67
- // Create a map of previous period data by date
68
- const previousDataMap = new Map();
69
- previousResponse.data.rows?.forEach((row) => {
70
- const dateStr = row.dimensionValues?.[0]?.value || '';
71
- if (dateStr) {
72
- previousDataMap.set(dateStr, parseInt(row.metricValues?.[0]?.value || '0'));
73
- }
74
- });
75
- // Combine current and previous period data
76
- const chartData = [];
77
- const daysInRange = Math.ceil((currentEndDate.getTime() - currentStartDate.getTime()) / (24 * 60 * 60 * 1000));
78
- for (let i = daysInRange - 1; i >= 0; i--) {
79
- const currentDate = new Date(currentEndDate);
80
- currentDate.setDate(currentDate.getDate() - i);
81
- const currentDateStr = currentDate.toISOString().split('T')[0].replace(/-/g, ''); // YYYYMMDD format
82
- // Calculate corresponding previous period date
83
- const previousDate = new Date(currentDate.getTime() - periodDuration);
84
- const previousDateStr = previousDate.toISOString().split('T')[0].replace(/-/g, ''); // YYYYMMDD format
85
- // Get current period data
86
- const currentRow = currentResponse.data.rows?.find((row) => row.dimensionValues?.[0]?.value === currentDateStr);
87
- const currentPageViews = parseInt(currentRow?.metricValues?.[0]?.value || '0');
88
- // Get previous period data
89
- const previousPageViews = previousDataMap.get(previousDateStr) || 0;
90
- // Format date for display
91
- const formattedDate = currentDate.toLocaleDateString('en-US', {
92
- month: 'short',
93
- day: 'numeric'
94
- });
95
- chartData.push({
96
- date: formattedDate,
97
- currentPageViews: currentPageViews,
98
- previousPageViews: previousPageViews,
99
- });
100
- }
101
- // Cache the result
102
- analyticsCache.set(cacheKey, chartData);
103
- return { success: true, data: chartData };
104
- }
105
- catch (error) {
106
- console.error('Google Analytics error:', error);
107
- return {
108
- success: false,
109
- error: error.message
110
- };
111
- }
112
- }
6
+ export {};