@newskit-render/core 0.0.0-d55b7d88

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 (456) hide show
  1. package/.ci/trigger-circleci-workflow.sh +37 -0
  2. package/.eslintignore +23 -0
  3. package/.eslintrc +74 -0
  4. package/.prettierignore +19 -0
  5. package/.prettierrc +7 -0
  6. package/CHANGELOG.md +7638 -0
  7. package/Dockerfile +14 -0
  8. package/Dockerfile.withNewRelic +15 -0
  9. package/README.md +274 -0
  10. package/__tests__/pages/__snapshots__/brightcove.test.tsx.snap +20 -0
  11. package/__tests__/pages/__snapshots__/home.test.tsx.snap +1195 -0
  12. package/__tests__/pages/brightcove.test.tsx +34 -0
  13. package/__tests__/pages/empty.test.tsx +10 -0
  14. package/__tests__/pages/home.test.tsx +16 -0
  15. package/app-context/InstrumentationContextProvider.tsx +36 -0
  16. package/assets/fontFamily.ts +416 -0
  17. package/assets/fonts/Graphik-Black-App.ttf +0 -0
  18. package/assets/fonts/Graphik-BlackItalic-App.ttf +0 -0
  19. package/assets/fonts/Graphik-Bold-App.ttf +0 -0
  20. package/assets/fonts/Graphik-BoldItalic-App.ttf +0 -0
  21. package/assets/fonts/Graphik-Extralight-App.ttf +0 -0
  22. package/assets/fonts/Graphik-ExtralightItalic-App.ttf +0 -0
  23. package/assets/fonts/Graphik-Light-App.ttf +0 -0
  24. package/assets/fonts/Graphik-LightItalic-App.ttf +0 -0
  25. package/assets/fonts/Graphik-Medium-App.ttf +0 -0
  26. package/assets/fonts/Graphik-Medium-Web.woff2 +0 -0
  27. package/assets/fonts/Graphik-MediumItalic-App.ttf +0 -0
  28. package/assets/fonts/Graphik-Regular-App.ttf +0 -0
  29. package/assets/fonts/Graphik-Regular-Web.woff2 +0 -0
  30. package/assets/fonts/Graphik-RegularItalic-App.ttf +0 -0
  31. package/assets/fonts/Graphik-Semibold-App.ttf +0 -0
  32. package/assets/fonts/Graphik-Semibold-Web.woff2 +0 -0
  33. package/assets/fonts/Graphik-SemiboldItalic-App.ttf +0 -0
  34. package/assets/fonts/Graphik-Super-App.ttf +0 -0
  35. package/assets/fonts/Graphik-SuperItalic-App.ttf +0 -0
  36. package/assets/fonts/Graphik-Thin-App.ttf +0 -0
  37. package/assets/fonts/Graphik-ThinItalic-App.ttf +0 -0
  38. package/assets/fonts/Montserrat-Black.ttf +0 -0
  39. package/assets/fonts/Montserrat-BlackItalic.ttf +0 -0
  40. package/assets/fonts/Montserrat-Bold.ttf +0 -0
  41. package/assets/fonts/Montserrat-BoldItalic.ttf +0 -0
  42. package/assets/fonts/Montserrat-ExtraBold.ttf +0 -0
  43. package/assets/fonts/Montserrat-ExtraBoldItalic.ttf +0 -0
  44. package/assets/fonts/Montserrat-ExtraLight.ttf +0 -0
  45. package/assets/fonts/Montserrat-ExtraLightItalic.ttf +0 -0
  46. package/assets/fonts/Montserrat-Italic.ttf +0 -0
  47. package/assets/fonts/Montserrat-Light.ttf +0 -0
  48. package/assets/fonts/Montserrat-LightItalic.ttf +0 -0
  49. package/assets/fonts/Montserrat-Medium.ttf +0 -0
  50. package/assets/fonts/Montserrat-MediumItalic.ttf +0 -0
  51. package/assets/fonts/Montserrat-Regular.ttf +0 -0
  52. package/assets/fonts/Montserrat-SemiBold.ttf +0 -0
  53. package/assets/fonts/Montserrat-SemiBoldItalic.ttf +0 -0
  54. package/assets/fonts/Montserrat-Thin.ttf +0 -0
  55. package/assets/fonts/Montserrat-ThinItalic.ttf +0 -0
  56. package/assets/fonts/PublicoHeadline-Black-App.ttf +0 -0
  57. package/assets/fonts/PublicoHeadline-BlackItalic-App.ttf +0 -0
  58. package/assets/fonts/PublicoHeadline-Bold-App.ttf +0 -0
  59. package/assets/fonts/PublicoHeadline-Bold-Web.woff2 +0 -0
  60. package/assets/fonts/PublicoHeadline-BoldItalic-App.ttf +0 -0
  61. package/assets/fonts/PublicoHeadline-Extrabold-App.ttf +0 -0
  62. package/assets/fonts/PublicoHeadline-ExtraboldItalic-App.ttf +0 -0
  63. package/assets/fonts/PublicoHeadline-Italic-App.ttf +0 -0
  64. package/assets/fonts/PublicoHeadline-Light-App.ttf +0 -0
  65. package/assets/fonts/PublicoHeadline-LightItalic-App.ttf +0 -0
  66. package/assets/fonts/PublicoHeadline-Medium-App.ttf +0 -0
  67. package/assets/fonts/PublicoHeadline-MediumItalic-App.ttf +0 -0
  68. package/assets/fonts/PublicoHeadline-Roman-App.ttf +0 -0
  69. package/assets/fonts/PublicoHeadline-Roman-Web.woff2 +0 -0
  70. package/assets/fonts/PublicoText-Bold-App.ttf +0 -0
  71. package/assets/fonts/PublicoText-BoldItalic-App.ttf +0 -0
  72. package/assets/fonts/PublicoText-Italic-App.ttf +0 -0
  73. package/assets/fonts/PublicoText-Italic-Web.woff2 +0 -0
  74. package/assets/fonts/PublicoText-Roman-App.ttf +0 -0
  75. package/assets/fonts/PublicoText-Roman-Web.woff2 +0 -0
  76. package/assets/fonts/PublicoText-Semibold-App.ttf +0 -0
  77. package/assets/fonts/PublicoText-SemiboldItalic-App.ttf +0 -0
  78. package/assets/fonts/Roboto-Bold.ttf +0 -0
  79. package/assets/fonts/Roboto-Light.ttf +0 -0
  80. package/assets/fonts/Roboto-Medium.ttf +0 -0
  81. package/assets/fonts/Roboto-Regular.ttf +0 -0
  82. package/assets/fonts/TheSun-Bold.ttf +0 -0
  83. package/assets/fonts/TheSun-BoldItalic.ttf +0 -0
  84. package/assets/fonts/TheSun-HeavyCondensed.ttf +0 -0
  85. package/assets/fonts/TheSun-HeavyNarrow.ttf +0 -0
  86. package/assets/fonts/TheSun-Italic.ttf +0 -0
  87. package/assets/fonts/TheSun-Medium.ttf +0 -0
  88. package/assets/fonts/TheSun-MediumItalic.ttf +0 -0
  89. package/assets/fonts/TheSun-Regular.ttf +0 -0
  90. package/assets/fonts/TimesDigital-Bold.ttf +0 -0
  91. package/assets/fonts/TimesDigital-BoldItalic.ttf +0 -0
  92. package/assets/fonts/TimesDigital-BoldSC.ttf +0 -0
  93. package/assets/fonts/TimesDigital-Italic.ttf +0 -0
  94. package/assets/fonts/TimesDigital-Regular.ttf +0 -0
  95. package/assets/fonts/TimesDigital-RegularSC.ttf +0 -0
  96. package/assets/fonts/TimesDigitalW04-Bold.ttf +0 -0
  97. package/assets/fonts/TimesDigitalW04-BoldItalic.ttf +0 -0
  98. package/assets/fonts/TimesDigitalW04-BoldSC.ttf +0 -0
  99. package/assets/fonts/TimesDigitalW04-Italic.ttf +0 -0
  100. package/assets/fonts/TimesDigitalW04-Regular.ttf +0 -0
  101. package/assets/fonts/TimesDigitalW04-RegularSC.ttf +0 -0
  102. package/assets/fonts/TimesModern-Regular.otf +0 -0
  103. package/assets/fonts/attribuitions.mdx +35 -0
  104. package/assets/fonts/bitter-medium.woff +0 -0
  105. package/assets/fonts/bitter-medium.woff2 +0 -0
  106. package/assets/fonts/bitter-mediumitalic.woff +0 -0
  107. package/assets/fonts/bitter-mediumitalic.woff2 +0 -0
  108. package/assets/fonts/bitter-regular.woff +0 -0
  109. package/assets/fonts/bitter-regular.woff2 +0 -0
  110. package/assets/fonts/bitter-semibold.woff +0 -0
  111. package/assets/fonts/bitter-semibold.woff2 +0 -0
  112. package/assets/fonts/dmmono-medium.woff +0 -0
  113. package/assets/fonts/dmmono-medium.woff2 +0 -0
  114. package/assets/fonts/dmsans-bold-webfont.woff +0 -0
  115. package/assets/fonts/dmsans-bold-webfont.woff2 +0 -0
  116. package/assets/fonts/dmsans-bolditalic-webfont.woff +0 -0
  117. package/assets/fonts/dmsans-bolditalic-webfont.woff2 +0 -0
  118. package/assets/fonts/dmsans-italic-webfont.woff +0 -0
  119. package/assets/fonts/dmsans-italic-webfont.woff2 +0 -0
  120. package/assets/fonts/dmsans-medium-webfont.woff +0 -0
  121. package/assets/fonts/dmsans-medium-webfont.woff2 +0 -0
  122. package/assets/fonts/dmsans-mediumitalic-webfont.woff +0 -0
  123. package/assets/fonts/dmsans-mediumitalic-webfont.woff2 +0 -0
  124. package/assets/fonts/dmsans-regular-webfont.woff +0 -0
  125. package/assets/fonts/dmsans-regular-webfont.woff2 +0 -0
  126. package/assets/fonts/notosans-bold-webfont.woff +0 -0
  127. package/assets/fonts/notosans-bold-webfont.woff2 +0 -0
  128. package/assets/fonts/notosans-italic-webfont.woff +0 -0
  129. package/assets/fonts/notosans-italic-webfont.woff2 +0 -0
  130. package/assets/fonts/notosans-medium-webfont.woff +0 -0
  131. package/assets/fonts/notosans-medium-webfont.woff2 +0 -0
  132. package/assets/fonts/notosans-regular-webfont.woff +0 -0
  133. package/assets/fonts/notosans-regular-webfont.woff2 +0 -0
  134. package/assets/fonts/poppins-bold-webfont.woff +0 -0
  135. package/assets/fonts/poppins-bold-webfont.woff2 +0 -0
  136. package/assets/fonts/poppins-bolditalic-webfont.woff +0 -0
  137. package/assets/fonts/poppins-bolditalic-webfont.woff2 +0 -0
  138. package/assets/fonts/poppins-extrabold-webfont.woff +0 -0
  139. package/assets/fonts/poppins-extrabold-webfont.woff2 +0 -0
  140. package/assets/fonts/poppins-extrabolditalic-webfont.woff +0 -0
  141. package/assets/fonts/poppins-extrabolditalic-webfont.woff2 +0 -0
  142. package/assets/fonts/poppins-italic-webfont.woff +0 -0
  143. package/assets/fonts/poppins-italic-webfont.woff2 +0 -0
  144. package/assets/fonts/poppins-light-webfont.woff +0 -0
  145. package/assets/fonts/poppins-light-webfont.woff2 +0 -0
  146. package/assets/fonts/poppins-lightitalic-webfont.woff +0 -0
  147. package/assets/fonts/poppins-lightitalic-webfont.woff2 +0 -0
  148. package/assets/fonts/poppins-medium-webfont.woff +0 -0
  149. package/assets/fonts/poppins-medium-webfont.woff2 +0 -0
  150. package/assets/fonts/poppins-mediumitalic-webfont.woff +0 -0
  151. package/assets/fonts/poppins-mediumitalic-webfont.woff2 +0 -0
  152. package/assets/fonts/poppins-regular-webfont.woff +0 -0
  153. package/assets/fonts/poppins-regular-webfont.woff2 +0 -0
  154. package/assets/fonts/poppins-semibold-webfont.woff +0 -0
  155. package/assets/fonts/poppins-semibold-webfont.woff2 +0 -0
  156. package/assets/fonts/poppins-semibolditalic-webfont.woff +0 -0
  157. package/assets/fonts/poppins-semibolditalic-webfont.woff2 +0 -0
  158. package/assets/fonts/source-serif-pro-600.woff +0 -0
  159. package/assets/fonts/source-serif-pro-600.woff2 +0 -0
  160. package/assets/fonts/source-serif-pro-600italic.woff +0 -0
  161. package/assets/fonts/source-serif-pro-600italic.woff2 +0 -0
  162. package/assets/fonts/source-serif-pro-700.woff +0 -0
  163. package/assets/fonts/source-serif-pro-700.woff2 +0 -0
  164. package/assets/fonts/source-serif-pro-700italic.woff +0 -0
  165. package/assets/fonts/source-serif-pro-700italic.woff2 +0 -0
  166. package/assets/fonts/source-serif-pro-italic.woff +0 -0
  167. package/assets/fonts/source-serif-pro-italic.woff2 +0 -0
  168. package/assets/fonts/source-serif-pro-regular.woff +0 -0
  169. package/assets/fonts/source-serif-pro-regular.woff2 +0 -0
  170. package/components/AccountDropdown/AccountDropdown.tsx +65 -0
  171. package/components/AccountDropdown/__tests__/AcountDropdown.test.tsx +83 -0
  172. package/components/AccountDropdown/accounts.ts +47 -0
  173. package/components/AccountDropdown/index.tsx +2 -0
  174. package/components/AccountDropdown/utils.ts +21 -0
  175. package/components/ErrorPage/ErrorPage.tsx +135 -0
  176. package/components/ad/index.tsx +35 -0
  177. package/components/article/Highlights.tsx +77 -0
  178. package/components/article/MetaBox.tsx +50 -0
  179. package/components/article/RelatedArticles.tsx +53 -0
  180. package/components/article/RelatedTopics.tsx +59 -0
  181. package/components/article/ShareBarComponent.tsx +53 -0
  182. package/components/article/__tests__/__snapshots__/index.test.tsx.snap +1568 -0
  183. package/components/article/__tests__/index.test.tsx +171 -0
  184. package/components/article/__tests__/mocks.ts +105 -0
  185. package/components/article/index.tsx +320 -0
  186. package/components/common/BackToHomepage.tsx +37 -0
  187. package/components/common/NavLink.tsx +26 -0
  188. package/components/common/NewskitLogo.tsx +52 -0
  189. package/components/common/NewskitLogoShort.tsx +48 -0
  190. package/components/common/SectionTitleBar.tsx +57 -0
  191. package/components/common/ShareButton.tsx +18 -0
  192. package/components/common/ViewMoreButton.tsx +20 -0
  193. package/components/common/iconNavLink/IconNavLink.tsx +70 -0
  194. package/components/common/iconNavLink/__tests__/IconNavLink.test.tsx +35 -0
  195. package/components/common/iconNavLink/index.ts +3 -0
  196. package/components/common/iconNavLink/types.ts +24 -0
  197. package/components/common/icons/IconAccount.tsx +13 -0
  198. package/components/common/icons/IconFilledTwitter.tsx +14 -0
  199. package/components/common/icons/StyledIconFilledChevronRight.tsx +12 -0
  200. package/components/footer/__snapshots__/index.test.tsx.snap +192 -0
  201. package/components/footer/index.test.tsx +13 -0
  202. package/components/footer/index.tsx +151 -0
  203. package/components/header/banner-messages.ts +39 -0
  204. package/components/header/index.tsx +52 -0
  205. package/components/header/navigation-links.ts +20 -0
  206. package/components/layout/Gutter.tsx +11 -0
  207. package/components/layout/LayoutTemplate.tsx +26 -0
  208. package/components/layout/MainGrid.tsx +66 -0
  209. package/components/layout/index.tsx +3 -0
  210. package/components/layout/layoutTypes.ts +13 -0
  211. package/components/section/ArticleSlice.tsx +35 -0
  212. package/components/section/CollectionBlock.tsx +54 -0
  213. package/components/section/SectionContext.tsx +9 -0
  214. package/components/section/__tests__/ArticleSlice.test.tsx +128 -0
  215. package/components/section/__tests__/CollectionBlock.test.tsx +83 -0
  216. package/components/section/__tests__/pageBlock.test.tsx +24 -0
  217. package/components/section/__tests__/sectionUtils.test.ts +94 -0
  218. package/components/section/index.tsx +39 -0
  219. package/components/section/layouts/Block.tsx +79 -0
  220. package/components/section/layouts/FallBack.tsx +24 -0
  221. package/components/section/layouts/Lead.tsx +43 -0
  222. package/components/section/layouts/Rows.tsx +82 -0
  223. package/components/section/layouts/SectionTitle.tsx +57 -0
  224. package/components/section/layouts/__tests__/Lead.test.tsx +37 -0
  225. package/components/section/layouts/__tests__/Rows.test.tsx +40 -0
  226. package/components/section/layouts/__tests__/SectionTitle.test.tsx +37 -0
  227. package/components/section/layouts/__tests__/__snapshots__/Lead.test.tsx.snap +180 -0
  228. package/components/section/layouts/__tests__/__snapshots__/SectionTitle.test.tsx.snap +354 -0
  229. package/components/section/layouts/gridUtils.ts +21 -0
  230. package/components/section/layouts/index.tsx +4 -0
  231. package/components/section/layouts/types.ts +13 -0
  232. package/components/section/pageBlock.tsx +23 -0
  233. package/components/section/sectionUtils.ts +61 -0
  234. package/components/teaser/index.test.tsx +50 -0
  235. package/components/teaser/index.tsx +64 -0
  236. package/components/teaser/teaserVariants.ts +33 -0
  237. package/components/teaser/variant-types.ts +49 -0
  238. package/components/teaser/variants/featureVariant.ts +42 -0
  239. package/components/teaser/variants/horizontal.ts +14 -0
  240. package/components/teaser/variants/titleTeaserVariant.ts +32 -0
  241. package/components/teaser/variants/titleVertical.ts +24 -0
  242. package/components/utils/index.test.ts +12 -0
  243. package/components/utils/index.ts +6 -0
  244. package/config/__tests__/index.test.ts +54 -0
  245. package/config/environment.ts +80 -0
  246. package/config/index.ts +2 -0
  247. package/config/multiTenancy.ts +11 -0
  248. package/constants/index.ts +2 -0
  249. package/context/app-context/AppContext.test.tsx +56 -0
  250. package/context/app-context/holidayStopListContextOverrides.ts +18 -0
  251. package/context/app-context/index.tsx +34 -0
  252. package/context/app-context/paymentMethodContext.tsx +70 -0
  253. package/context/index.tsx +2 -0
  254. package/context/multi-tenancy/MultiTenancy.test.tsx +48 -0
  255. package/context/multi-tenancy/index.tsx +32 -0
  256. package/css/index.ts +15 -0
  257. package/cypress/axe/terminal-log.js +19 -0
  258. package/cypress/config/visual.config.ts +11 -0
  259. package/cypress/config/visual.skip.config.ts +10 -0
  260. package/cypress/e2e/account/accessibility.cy.js +88 -0
  261. package/cypress/e2e/account/banners.cy.js +169 -0
  262. package/cypress/e2e/account/cancellation.cy.js +219 -0
  263. package/cypress/e2e/account/holiday-stops.cy.js +109 -0
  264. package/cypress/e2e/account/main-api.cy.js +102 -0
  265. package/cypress/e2e/account/newsletters-and-alerts.cy.js +149 -0
  266. package/cypress/e2e/account/newsletters-page.cy.js +69 -0
  267. package/cypress/e2e/account/payment-page.cy.js +98 -0
  268. package/cypress/e2e/account/personal-details.cy.js +1161 -0
  269. package/cypress/e2e/account/subscription-and-billing.cy.js +434 -0
  270. package/cypress/e2e/checkout/account-creation.cy.js +8 -0
  271. package/cypress/e2e/checkout/payment-details.cy.js +19 -0
  272. package/cypress/e2e/core/home-page.cy.js +6 -0
  273. package/cypress/e2e/help-hub/accessibility.cy.js +35 -0
  274. package/cypress/e2e/help-hub/article-page.cy.js +115 -0
  275. package/cypress/e2e/help-hub/landing-page.cy.js +94 -0
  276. package/cypress/e2e/help-hub/result-page.cy.js +117 -0
  277. package/cypress/fixtures/empty.html +10 -0
  278. package/cypress/fixtures/example.json +5 -0
  279. package/cypress/fixtures/holiday-stops.json +40 -0
  280. package/cypress/fixtures/paymentFailure.js +24 -0
  281. package/cypress/fixtures/testDates.js +26 -0
  282. package/cypress/support/commands.js +125 -0
  283. package/cypress/support/consentValues.js +5839 -0
  284. package/cypress/support/e2e.js +22 -0
  285. package/cypress/support/users.js +58 -0
  286. package/cypress/visual/account/print-visual-regression.cy.js +9 -0
  287. package/cypress/visual/account/visual-regression.cy.js +40 -0
  288. package/cypress/visual/empty/empty.cy.js +5 -0
  289. package/cypress.config.ts +38 -0
  290. package/helpers/__tests__/getUser.test.ts +45 -0
  291. package/helpers/__tests__/logger.test.ts +62 -0
  292. package/helpers/__tests__/useThemeDropdownObject.test.ts +49 -0
  293. package/helpers/a11y.ts +7 -0
  294. package/helpers/addCacheHeaders.ts +8 -0
  295. package/helpers/getUser.ts +37 -0
  296. package/helpers/getYear.ts +1 -0
  297. package/helpers/global-types.ts +186 -0
  298. package/helpers/logger/getWinstonLogger.ts +19 -0
  299. package/helpers/logger/index.ts +20 -0
  300. package/helpers/logger/replaceConsoleWithLogger.ts +14 -0
  301. package/helpers/mocks/articleMock.ts +50 -0
  302. package/helpers/mocks/getPageMock.ts +369 -0
  303. package/helpers/mocks/getRadioPostMock.ts +71 -0
  304. package/helpers/mocks/getRadioPostsMock.ts +26 -0
  305. package/helpers/mocks/getRecommendationsMock.ts +20 -0
  306. package/helpers/mocks/index.ts +7 -0
  307. package/helpers/multiTenancy.ts +19 -0
  308. package/helpers/setupTests.ts +5 -0
  309. package/helpers/test-utils.tsx +33 -0
  310. package/helpers/useThemeDropdownObject.tsx +73 -0
  311. package/infrastructure/.circleci/config.yml +1187 -0
  312. package/infrastructure/INFRASTRUCTURE.md +142 -0
  313. package/infrastructure/build_and_deploy.png +0 -0
  314. package/infrastructure/helm/Chart.yaml +21 -0
  315. package/infrastructure/helm/templates/_helpers.tpl +87 -0
  316. package/infrastructure/helm/templates/deployment.yaml +45 -0
  317. package/infrastructure/helm/templates/horizontalpodautoscaler.yaml +21 -0
  318. package/infrastructure/helm/templates/ingress.yaml +31 -0
  319. package/infrastructure/helm/templates/networkpolicy.yaml +26 -0
  320. package/infrastructure/helm/templates/secret.yaml +12 -0
  321. package/infrastructure/helm/templates/service.yaml +15 -0
  322. package/infrastructure/helm/values-dev.yaml +39 -0
  323. package/infrastructure/helm/values-local.yaml +30 -0
  324. package/infrastructure/helm/values-pr.yaml +40 -0
  325. package/infrastructure/helm/values-prod.yaml +39 -0
  326. package/infrastructure/helm/values-staging.yaml +39 -0
  327. package/infrastructure/helm/values.yaml +44 -0
  328. package/infrastructure/pull_request.png +0 -0
  329. package/infrastructure/release-documentation-cli.config.json +18 -0
  330. package/infrastructure/remove_pr.png +0 -0
  331. package/infrastructure/terraform-ecr/dev.tfvars +3 -0
  332. package/infrastructure/terraform-ecr/ecr.tf +69 -0
  333. package/infrastructure/terraform-ecr/main.tf +3 -0
  334. package/infrastructure/terraform-ecr/variables.tf +19 -0
  335. package/infrastructure/terraform-ecr/versions.tf +12 -0
  336. package/infrastructure/terraform-newrelic/alerts.tf +290 -0
  337. package/infrastructure/terraform-newrelic/dashboards.tf +347 -0
  338. package/infrastructure/terraform-newrelic/dev.tfvars +3 -0
  339. package/infrastructure/terraform-newrelic/lighthouse-script-dev.js +53 -0
  340. package/infrastructure/terraform-newrelic/lighthouse-script-prod.js +54 -0
  341. package/infrastructure/terraform-newrelic/lighthouse-script-stage.js +54 -0
  342. package/infrastructure/terraform-newrelic/main.tf +11 -0
  343. package/infrastructure/terraform-newrelic/monitors.tf +11 -0
  344. package/infrastructure/terraform-newrelic/prod.tfvars +3 -0
  345. package/infrastructure/terraform-newrelic/staging.tfvars +3 -0
  346. package/infrastructure/terraform-newrelic/variables.tf +33 -0
  347. package/infrastructure/terraform-newrelic/versions.tf +18 -0
  348. package/jest.config.js +40 -0
  349. package/jest.config.pact.js +18 -0
  350. package/newrelic.js +86 -0
  351. package/next-env.d.ts +5 -0
  352. package/next.config.js +95 -0
  353. package/package.json +127 -0
  354. package/pages/_app.tsx +117 -0
  355. package/pages/_document.tsx +112 -0
  356. package/pages/_error.tsx +68 -0
  357. package/pages/account/add/[field].tsx +34 -0
  358. package/pages/account/cancellation/index.tsx +22 -0
  359. package/pages/account/delete/confirm/index.tsx +16 -0
  360. package/pages/account/delete/error/index.tsx +16 -0
  361. package/pages/account/delete/index.tsx +16 -0
  362. package/pages/account/delete/success/index.tsx +16 -0
  363. package/pages/account/dream-team/index.tsx +19 -0
  364. package/pages/account/edit/[field].tsx +45 -0
  365. package/pages/account/family/index.tsx +19 -0
  366. package/pages/account/holiday-stop/index.tsx +19 -0
  367. package/pages/account/holiday-stop/previous-holiday-stops.tsx +19 -0
  368. package/pages/account/holiday-stop/upcoming-holiday-stops.tsx +19 -0
  369. package/pages/account/index.tsx +33 -0
  370. package/pages/account/newsletters/index.tsx +19 -0
  371. package/pages/account/newsletters-and-alerts/index.tsx +24 -0
  372. package/pages/account/payment/[paymentMethod].tsx +37 -0
  373. package/pages/account/payment/index.tsx +23 -0
  374. package/pages/account/payment-methods/index.tsx +21 -0
  375. package/pages/account/subscription-and-billing/index.tsx +29 -0
  376. package/pages/api/account/get-session/index.ts +33 -0
  377. package/pages/api/account/invoice/index.ts +35 -0
  378. package/pages/api/account/mutate/index.ts +8 -0
  379. package/pages/api/account/query/index.ts +7 -0
  380. package/pages/api/auth/[...nextauth].ts +11 -0
  381. package/pages/api/competitions-sitemap.ts +19 -0
  382. package/pages/api/feed.ts +23 -0
  383. package/pages/api/health-check.ts +7 -0
  384. package/pages/api/news-sitemap.ts +18 -0
  385. package/pages/api/pages-sitemap.ts +27 -0
  386. package/pages/api/robots.ts +19 -0
  387. package/pages/api/sitemap.ts +24 -0
  388. package/pages/checkout/account-creation/index.tsx +13 -0
  389. package/pages/checkout/payment-details/index.tsx +10 -0
  390. package/pages/empty.tsx +6 -0
  391. package/pages/help-hub/article/[title]/index.tsx +25 -0
  392. package/pages/help-hub/error.tsx +23 -0
  393. package/pages/help-hub/index.tsx +51 -0
  394. package/pages/help-hub/results.tsx +25 -0
  395. package/pages/index.tsx +19 -0
  396. package/pages/player/brightcove.tsx +19 -0
  397. package/pages/rss/create/index.tsx +18 -0
  398. package/pages/rss/feed/[feedId]/index.tsx +21 -0
  399. package/pages/rss/index.tsx +18 -0
  400. package/public/ads.min.js +8175 -0
  401. package/public/assets/display-base-header.svg +25 -0
  402. package/public/assets/display-personalDetails-header-sun.svg +55 -0
  403. package/public/assets/display-personalDetails-header-times.svg +90 -0
  404. package/public/assets/display-personalDetails-header-vr.svg +46 -0
  405. package/public/assets/dream-team.svg +10 -0
  406. package/public/assets/navigationPrimary-brandMark-sun.svg +9 -0
  407. package/public/assets/navigationPrimary-brandMark-times.svg +18 -0
  408. package/public/assets/navigationPrimary-brandMark-vr.svg +10 -0
  409. package/public/assets/newsletters/bestoftimes-101.png +0 -0
  410. package/public/assets/newsletters/books-115.png +0 -0
  411. package/public/assets/newsletters/environment-140.png +0 -0
  412. package/public/assets/newsletters/fashion-108.png +0 -0
  413. package/public/assets/newsletters/food-106.png +0 -0
  414. package/public/assets/newsletters/football-111.png +0 -0
  415. package/public/assets/newsletters/ireland-152.png +0 -0
  416. package/public/assets/newsletters/law-121.png +0 -0
  417. package/public/assets/newsletters/money-107.png +0 -0
  418. package/public/assets/newsletters/moneymentor-150.png +0 -0
  419. package/public/assets/newsletters/placeholder.png +0 -0
  420. package/public/assets/newsletters/politics-119.png +0 -0
  421. package/public/assets/newsletters/property-113.png +0 -0
  422. package/public/assets/newsletters/puzzles-125.png +0 -0
  423. package/public/assets/newsletters/scotland-134.png +0 -0
  424. package/public/assets/newsletters/theatre-127.png +0 -0
  425. package/public/assets/newsletters/travel-149.png +0 -0
  426. package/public/assets/newsletters/tv-133.png +0 -0
  427. package/public/assets/newsletters/us-153.png +0 -0
  428. package/public/assets/no-subscription.svg +15 -0
  429. package/public/assets/pending-activation.svg +16 -0
  430. package/public/assets/personal-details-header.svg +91 -0
  431. package/public/assets/plchldr150x100.png +0 -0
  432. package/public/assets/previous-subscription.svg +15 -0
  433. package/public/assets/primary-navigation-logo-white.svg +6 -0
  434. package/public/assets/primary-navigation-logo.svg +6 -0
  435. package/public/assets/tls-logo-white.svg +3 -0
  436. package/public/favicon.ico +0 -0
  437. package/public/icon.png +0 -0
  438. package/public/prebid.min.js +1 -0
  439. package/queries/getPage.ts +100 -0
  440. package/queries/getRadioPost.ts +61 -0
  441. package/queries/getRadioPosts.ts +16 -0
  442. package/queries/getUserSubscription.ts +9 -0
  443. package/queries/index.ts +3 -0
  444. package/scripts/k8s-local.sh +137 -0
  445. package/scripts/nr-exports.sh +7 -0
  446. package/temp/_app.tsx +15 -0
  447. package/temp/_document.tsx +61 -0
  448. package/temp/app-context-test.tsx +51 -0
  449. package/temp/app-context.tsx +25 -0
  450. package/temp/config-index.ts +1 -0
  451. package/temp/context-index.tsx +1 -0
  452. package/temp/header.tsx +45 -0
  453. package/temp/next.config.js +56 -0
  454. package/tsconfig.json +51 -0
  455. package/tsconfig.test.json +6 -0
  456. package/validation/index.tsx +24 -0
@@ -0,0 +1,22 @@
1
+ // ***********************************************************
2
+ // This example support/index.js is processed and
3
+ // loaded automatically before your test files.
4
+ //
5
+ // This is a great place to put global configuration and
6
+ // behavior that modifies Cypress.
7
+ //
8
+ // You can change the location of this file or turn off
9
+ // automatically serving support files with the
10
+ // 'supportFile' configuration option.
11
+ //
12
+ // You can read more here:
13
+ // https://on.cypress.io/configuration
14
+ // ***********************************************************
15
+
16
+ // Import commands.js using ES2015 syntax:
17
+ import './commands'
18
+ import 'cypress-axe'
19
+ import '@percy/cypress';
20
+
21
+ // Alternatively you can use CommonJS syntax:
22
+ // require('./commands')
@@ -0,0 +1,58 @@
1
+ // All accounts are created in staging environment
2
+ export const userMap = {
3
+ default: {
4
+ username: 'render.e2e.default@yopmail.com', // Sun
5
+ password: 'Ad45p0-swq151@',
6
+ },
7
+ noSub: {
8
+ username: 'render.e2e.no-sub@yopmail.com', // Sun
9
+ password: 'Ad45p0-swq151@',
10
+ },
11
+ expiredSub: {
12
+ username: 'tim.newsuk3@yopmail.com', // Sun
13
+ password: 'Ad45p0-swq151@',
14
+ },
15
+ withSub: {
16
+ username: 'render-e2e-subscription@yopmail.com', // Sun
17
+ password: 'Testing123$',
18
+ },
19
+ paypalSub: {
20
+ username: 'render-paypal-payment@yopmail.com', // Sun
21
+ password: 'testing123',
22
+ },
23
+ tnl: {
24
+ username: 'cmp1aug2022printstag@yopmail.com', //Print user
25
+ password: 'Password123',
26
+ },
27
+ digitalCard: {
28
+ //dtc=false
29
+ username: 'cmp-digi-card-20-09-22@yopmail.com',
30
+ password: 'Password123',
31
+ },
32
+ digitalDirectDebit: {
33
+ //dtc=false
34
+ username: 'cmp-digi-direct-20-09-22@yopmail.com',
35
+ password: 'Password123',
36
+ },
37
+ print: {
38
+ //dtc=true
39
+ username: 'cmp-dtc-card-20-09-22@yopmail.com',
40
+ password: 'Password123',
41
+ },
42
+ printVouchers: {
43
+ //dtc=false
44
+ username: 'cmp-test-direct-20-09-22@yopmail.com',
45
+ password: 'Password123',
46
+ },
47
+ digiprint: {
48
+ //dtc=true
49
+ username: 'digi-print.dtc.test@yopmail.com',
50
+ password: 'Password123',
51
+ },
52
+ digiprintVouchers: {
53
+ //dtc=false
54
+ username: 'digi-print-card-15-11-22@yopmail.com',
55
+ password: 'Password123',
56
+ },
57
+ }
58
+
@@ -0,0 +1,9 @@
1
+ describe('Visual regression for print and digi_print subscriptions', () => {
2
+ it('should show sections for print user subscriptions', () => {
3
+ cy.GetTnlAcsSession('print')
4
+ cy.mockConsentAndVisit('/account/subscription-and-billing')
5
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
6
+ cy.wait(1000)
7
+ cy.percySnapshot('Subscription and Billing page for print subscriptions')
8
+ })
9
+ })
@@ -0,0 +1,40 @@
1
+ const pages = [
2
+ { url: '/account', pageName: 'Personal Details' },
3
+ { url: '/account/edit/name', pageName: 'Name form' },
4
+ { url: '/account/edit/email', pageName: 'Email form' },
5
+ { url: '/account/edit/password', pageName: 'Password from' },
6
+ { url: '/account/edit/mobile', pageName: 'Mobile phone from' },
7
+ { url: '/account/edit/address', pageName: 'Address form' },
8
+ { url: '/account/cancellation', pageName: 'Cancel reason' },
9
+ {
10
+ url: '/account/subscription-and-billing',
11
+ pageName: 'Subscription and Billing',
12
+ },
13
+ {
14
+ url: '/account/newsletters-and-alerts',
15
+ pageName: 'Newsletters and Alerts',
16
+ },
17
+ {
18
+ url: '/account/edit/commenting-notifications',
19
+ pageName: 'Commenting Notifications form',
20
+ },
21
+ {
22
+ url: '/account/edit/delivery-instructions',
23
+ pageName: 'delivery instructions form',
24
+ },
25
+ {
26
+ url: '/account/holiday-stop',
27
+ pageName: 'Holiday Stops',
28
+ },
29
+ ]
30
+
31
+ describe('Visual regression', () => {
32
+ pages.forEach(({ url, pageName }) => {
33
+ it(`should pass regression: ${pageName}`, () => {
34
+ cy.mockConsentAndVisit(url)
35
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
36
+ cy.wait(1000)
37
+ cy.percySnapshot(`${pageName} page`)
38
+ })
39
+ })
40
+ })
@@ -0,0 +1,5 @@
1
+ // Running this empty test is a workaround to skip the visual tests when no visual changes have been made.
2
+ it(`should always pass empty test`, { baseUrl: null }, () => {
3
+ cy.visit('./cypress/fixtures/empty.html')
4
+ cy.percySnapshot()
5
+ })
@@ -0,0 +1,38 @@
1
+ import { defineConfig } from 'cypress'
2
+ import { loadEnvConfig } from '@next/env'
3
+
4
+ export default defineConfig({
5
+ video: false,
6
+ screenshotOnRunFailure: true,
7
+ defaultCommandTimeout: 50000,
8
+ chromeWebSecurity: false,
9
+ retries: 1,
10
+ env: {
11
+ E2E_BASE_URL: 'http://localhost:3000/api/account',
12
+ ACCOUNT_PROVIDER_GRAPHQL_URL:
13
+ 'https://main-graphql.staging.newsapis.co.uk/graphql',
14
+ ACCOUNT_PROVIDER_COOKIE_NAME: 'acs_ngn',
15
+ },
16
+ e2e: {
17
+ setupNodeEvents(on, config) {
18
+ const projectDir = process.cwd()
19
+ loadEnvConfig(projectDir)
20
+
21
+ on('task', {
22
+ log(message) {
23
+ console.log(message)
24
+ return null
25
+ },
26
+ table(message) {
27
+ console.table(message)
28
+ return null
29
+ },
30
+ })
31
+
32
+ return config
33
+ },
34
+ baseUrl: 'http://localhost:3000',
35
+ specPattern: './cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
36
+ excludeSpecPattern: './cypress/e2e/checkout/*.cy.{js,jsx,ts,tsx}',
37
+ },
38
+ })
@@ -0,0 +1,45 @@
1
+ import fetch from 'cross-fetch'
2
+ import { fetchUser } from '../getUser'
3
+
4
+ jest.mock('cross-fetch', () => jest.fn().mockImplementation(() => {}))
5
+
6
+ describe('getUser function', () => {
7
+ beforeEach(() => {
8
+ jest.clearAllMocks()
9
+ })
10
+ it("should call console.error with 'Bad response from server' when Response.status >= 400", async () => {
11
+ jest.spyOn(console, 'error')
12
+ ;(fetch as jest.Mock).mockImplementation(() =>
13
+ Promise.resolve({ status: 500 })
14
+ )
15
+ await fetchUser(
16
+ { Cookie: 'test' },
17
+ 'http://localhost:3000/api/account/query'
18
+ )
19
+ expect(console.error).toHaveBeenCalledWith('Bad response from server')
20
+ })
21
+
22
+ it('should call response.json() when Response.status is < 400', async () => {
23
+ const mockJson = jest.fn()
24
+ ;(fetch as jest.Mock).mockImplementation(() =>
25
+ Promise.resolve({ status: 200, json: mockJson })
26
+ )
27
+ await fetchUser(
28
+ { Cookie: 'test' },
29
+ 'http://localhost:3000/api/account/query'
30
+ )
31
+ expect(mockJson).toHaveBeenCalled()
32
+ })
33
+
34
+ it('should return null if no cookie', async () => {
35
+ const mockJson = jest.fn()
36
+ ;(fetch as jest.Mock).mockImplementation(() =>
37
+ Promise.resolve({ status: 200, json: mockJson })
38
+ )
39
+ await fetchUser(
40
+ "I'm not a cookie",
41
+ 'http://localhost:3000/api/account/query'
42
+ )
43
+ expect(mockJson).not.toHaveBeenCalled()
44
+ })
45
+ })
@@ -0,0 +1,62 @@
1
+ import { replaceConsoleWithLogger } from '../logger'
2
+
3
+ describe('logger', () => {
4
+ const { window } = global
5
+
6
+ const loggerMock = {
7
+ debug: jest.fn(),
8
+ warn: jest.fn(),
9
+ info: jest.fn(),
10
+ error: jest.fn(),
11
+ }
12
+
13
+ beforeEach(() => {
14
+ delete global.window
15
+ jest.resetAllMocks()
16
+ })
17
+ afterEach(() => {
18
+ global.window = window
19
+ })
20
+
21
+ it('should not replace console.log with Wintson', () => {
22
+ const replaceConsole = replaceConsoleWithLogger(loggerMock, 'false')
23
+ replaceConsole()
24
+ console.log('test')
25
+ expect(loggerMock.info).not.toBeCalledWith('test')
26
+ })
27
+
28
+ it('should replace console.log with Wintson', () => {
29
+ const replaceConsole = replaceConsoleWithLogger(loggerMock, 'true')
30
+ replaceConsole()
31
+ console.log('test')
32
+ expect(loggerMock.info).toBeCalledWith('test')
33
+ })
34
+
35
+ it('should replace console.info with Wintson', () => {
36
+ const replaceConsole = replaceConsoleWithLogger(loggerMock, 'true')
37
+ replaceConsole()
38
+ console.info('test')
39
+ expect(loggerMock.info).toBeCalledWith('test')
40
+ })
41
+
42
+ it('should replace console.warn with Wintson', () => {
43
+ const replaceConsole = replaceConsoleWithLogger(loggerMock, 'true')
44
+ replaceConsole()
45
+ console.warn('test')
46
+ expect(loggerMock.warn).toBeCalledWith('test')
47
+ })
48
+
49
+ it('should replace console.error with Wintson', () => {
50
+ const replaceConsole = replaceConsoleWithLogger(loggerMock, 'true')
51
+ replaceConsole()
52
+ console.error('test')
53
+ expect(loggerMock.error).toBeCalledWith('test')
54
+ })
55
+
56
+ it('should replace console.debug with Wintson', () => {
57
+ const replaceConsole = replaceConsoleWithLogger(loggerMock, 'true')
58
+ replaceConsole()
59
+ console.debug('test')
60
+ expect(loggerMock.debug).toBeCalledWith('test')
61
+ })
62
+ })
@@ -0,0 +1,49 @@
1
+ import { useThemeDropdownObject } from '../useThemeDropdownObject'
2
+
3
+ jest.mock('react', () => ({
4
+ ...jest.requireActual('react'),
5
+ useState: jest.fn().mockReturnValue([false, {}]),
6
+ }))
7
+
8
+ describe('createThemeDropdownObject', () => {
9
+ const setTheme = jest.fn()
10
+ test('should return themeDropdownObject', () => {
11
+ const themeDropdownObject = useThemeDropdownObject(setTheme)
12
+ expect(themeDropdownObject).toEqual({
13
+ clientHeaderImages: {
14
+ 'The-Sun': 'display-personalDetails-header-sun.svg',
15
+ 'Virgin-Radio': 'display-personalDetails-header-vr.svg',
16
+ 'The-Times': 'display-personalDetails-header-times.svg',
17
+ },
18
+ clientNavigationLogos: {
19
+ 'The-Sun': {
20
+ src: '/assets/navigationPrimary-brandMark-sun.svg',
21
+ width: '140px',
22
+ height: '48px',
23
+ top: '0',
24
+ },
25
+ 'Virgin-Radio': {
26
+ src: '/assets/navigationPrimary-brandMark-vr.svg',
27
+ width: '150px',
28
+ height: '41px',
29
+ top: '0',
30
+ },
31
+ 'The-Times': {
32
+ src: '/assets/navigationPrimary-brandMark-times.svg',
33
+ width: '150px',
34
+ height: '40px',
35
+ top: '0',
36
+ },
37
+ TLS: {
38
+ height: '40px',
39
+ src: '/assets/tls-logo-white.svg',
40
+ top: '0',
41
+ width: '150px',
42
+ },
43
+ },
44
+ options: expect.any(Object),
45
+ themeDropdownOpen: false,
46
+ dropdown: expect.any(Function),
47
+ })
48
+ })
49
+ })
@@ -0,0 +1,7 @@
1
+ export const handleEnterKeyPress =
2
+ (onClick: () => void) =>
3
+ ({ key }: { key: string }) => {
4
+ if (key === 'Enter') {
5
+ onClick()
6
+ }
7
+ }
@@ -0,0 +1,8 @@
1
+ import { ServerResponse } from 'http'
2
+
3
+ export const addCacheHeaders = (res: ServerResponse) => {
4
+ res.setHeader(
5
+ 'Cache-Control',
6
+ 'public, s-maxage=10, stale-while-revalidate=59'
7
+ )
8
+ }
@@ -0,0 +1,37 @@
1
+ import fetch from 'cross-fetch'
2
+ import { UserData } from '@newskit-render/my-account'
3
+ import { MainAcsCookie } from '@newskit-render/api'
4
+
5
+ interface UserHeaders {
6
+ [key: string]: string
7
+ }
8
+ interface UserConfig {
9
+ method: string
10
+ headers: UserHeaders
11
+ body: string
12
+ }
13
+
14
+ const userConfig = (acsCookie: { Cookie: string }): UserConfig => ({
15
+ method: 'POST',
16
+ headers: {
17
+ 'Content-Type': 'application/json',
18
+ ...acsCookie,
19
+ },
20
+ body: JSON.stringify({ queryFragment: 'UserPaymentInfo' }),
21
+ })
22
+
23
+ export const fetchUser = async (
24
+ acsCookie: MainAcsCookie,
25
+ url: string
26
+ ): Promise<UserData | null> => {
27
+ if (typeof acsCookie === 'object') {
28
+ const response = await fetch(url, userConfig(acsCookie))
29
+
30
+ if (response.status >= 400) {
31
+ console.error('Bad response from server')
32
+ return null
33
+ }
34
+ return (await response.json()) as UserData
35
+ }
36
+ return null
37
+ }
@@ -0,0 +1 @@
1
+ export const getYear = () => new Date().getFullYear()
@@ -0,0 +1,186 @@
1
+ declare global {
2
+ interface Window {
3
+ utag: Record<string, TealiumData>
4
+ }
5
+ }
6
+ interface TealiumData {
7
+ data: Record<string, string>
8
+ }
9
+ export enum ContentType {
10
+ article,
11
+ post,
12
+ }
13
+
14
+ export type RadioPost = {
15
+ id: number
16
+ type: ContentType
17
+ headline: string
18
+ body: Array<Object>
19
+ dateCreated: string
20
+ datePublished: string
21
+ dateUpdated?: string
22
+ }
23
+
24
+ export type RadioPosts = Array<RadioPost>
25
+
26
+ export type Layout = 'vertical' | 'horizontal' | 'horizontal-reverse'
27
+
28
+ export type TeaserSummary = {
29
+ children?: {
30
+ text: string
31
+ }[]
32
+ }
33
+
34
+ export type TeaserCategory = {
35
+ slug: string
36
+ }
37
+
38
+ export type ArticleTeaser = {
39
+ id?: string
40
+ slug?: string
41
+ categories?: TeaserCategory[]
42
+ topics?: {
43
+ name: string
44
+ slug: string
45
+ }[]
46
+ kicker?: string
47
+ headline?: string
48
+ media?: Media
49
+ summary?: TeaserSummary
50
+ }
51
+
52
+ export type ArticleBlock = {
53
+ type: string
54
+ article: ArticleTeaser
55
+ }
56
+
57
+ export type VideoBrightcoveBlock = {
58
+ accountId: string
59
+ id: string
60
+ playerId: string
61
+ type: string
62
+ }
63
+
64
+ export type ExternalReferenceBlock = {
65
+ author: {
66
+ id: string
67
+ type: string
68
+ }
69
+ headline: string
70
+ image: {
71
+ alt: string
72
+ caption: string
73
+ credit: string
74
+ type: string
75
+ url: string
76
+ }
77
+ label: string
78
+ type: string
79
+ url: string
80
+ }
81
+
82
+ export type SliceBlock =
83
+ | ArticleBlock
84
+ | VideoBrightcoveBlock
85
+ | ExternalReferenceBlock
86
+
87
+ export type ArticleSlice = {
88
+ name: string
89
+ type: string
90
+ children: SliceBlock[]
91
+ }
92
+
93
+ export type TopicAuthorSlice = {
94
+ type: string
95
+ }
96
+
97
+ export type CollectionSlice = ArticleSlice | TopicAuthorSlice
98
+
99
+ export type CollectionBlock = {
100
+ id: string
101
+ type: string
102
+ title?: string
103
+ link?: {
104
+ url: string
105
+ text?: string
106
+ }
107
+ children: CollectionSlice[]
108
+ }
109
+
110
+ export type ImageBlock = {
111
+ type: string
112
+ }
113
+
114
+ export type TweetBlock = {
115
+ type: string
116
+ }
117
+
118
+ export type PageBlock =
119
+ | CollectionBlock
120
+ | ImageBlock
121
+ | TweetBlock
122
+ | ParagraphBlock
123
+
124
+ export type Page = {
125
+ id: string
126
+ title: string
127
+ slug: string
128
+ body: PageBlock[]
129
+ }
130
+
131
+ export type Media = Image | Video
132
+
133
+ export type Image = {
134
+ crops: ImageCrop[]
135
+ crop?: ImageCrop
136
+ }
137
+
138
+ export type Video = {
139
+ videoId: string
140
+ accountId?: string
141
+ posterImage?: Image
142
+ }
143
+
144
+ export type ImageCrop = {
145
+ url?: string
146
+ alt?: string
147
+ aspectRatio?: string
148
+ }
149
+
150
+ export type Byline = AuthorByline | TextByline
151
+
152
+ export type AuthorByline = {
153
+ type: string
154
+ slug: string
155
+ name: string
156
+ }
157
+
158
+ export type TextByline = {
159
+ type: string
160
+ value: string
161
+ }
162
+
163
+ export type Slug = string & { _: 'Slug' }
164
+ export type URL = string & { _: 'Url' }
165
+
166
+ export type Topic = {
167
+ name: string
168
+ slug?: string
169
+ link?: URL
170
+ }
171
+
172
+ export type ParagraphBlock = {
173
+ type?: string
174
+ children: ArticleParagraphChildren[]
175
+ }
176
+
177
+ export type ArticleParagraphChildren = ArticleText | ArticleHyperlink
178
+
179
+ export type ArticleText = {
180
+ text: string
181
+ }
182
+
183
+ export type ArticleHyperlink = {
184
+ url: string
185
+ text?: string
186
+ }
@@ -0,0 +1,19 @@
1
+ import winston, { Logger } from 'winston'
2
+ import newrelicFormatter from '@newrelic/winston-enricher'
3
+
4
+ const newrelicWinstonFormatter = newrelicFormatter(winston)
5
+
6
+ export const getWinstonLogger = (winstonLogLevel?: string): Logger =>
7
+ winston.createLogger({
8
+ level: winstonLogLevel || 'info',
9
+ format: winston.format.json(),
10
+ transports: [
11
+ new winston.transports.Console({
12
+ format: winston.format.combine(
13
+ winston.format.timestamp({ format: 'DD-MM-YYYY T hh:mm:ss.sss A' }),
14
+ winston.format.json(),
15
+ newrelicWinstonFormatter()
16
+ ),
17
+ }),
18
+ ],
19
+ })
@@ -0,0 +1,20 @@
1
+ import newrelic from 'newrelic'
2
+ import { winstonEnabled, winstonLogLevel } from '../../config'
3
+ import { getWinstonLogger } from './getWinstonLogger'
4
+ import { replaceConsoleWithLogger } from './replaceConsoleWithLogger'
5
+
6
+ const logger = getWinstonLogger(winstonLogLevel)
7
+ const replaceConsole = replaceConsoleWithLogger(logger, winstonEnabled)
8
+
9
+ const replaceConsoleAndSetTransactionName = (transactionName: string) => {
10
+ replaceConsole()
11
+
12
+ newrelic.setTransactionName(transactionName)
13
+ }
14
+
15
+ export {
16
+ logger,
17
+ replaceConsoleWithLogger,
18
+ replaceConsole,
19
+ replaceConsoleAndSetTransactionName,
20
+ }
@@ -0,0 +1,14 @@
1
+ import { Logger } from 'winston'
2
+
3
+ export const replaceConsoleWithLogger =
4
+ (logger: Logger, winstonEnabled?: string) => () => {
5
+ if (winstonEnabled === 'true') {
6
+ console.log = (...message: any[]) => logger.info.call(logger, ...message)
7
+ console.info = (...message: any[]) => logger.info.call(logger, ...message)
8
+ console.warn = (...message: any[]) => logger.warn.call(logger, ...message)
9
+ console.error = (...message: any[]) =>
10
+ logger.error.call(logger, ...message)
11
+ console.debug = (...message: any[]) =>
12
+ logger.debug.call(logger, ...message)
13
+ }
14
+ }
@@ -0,0 +1,50 @@
1
+ const imagePlaceholderHref = (res) =>
2
+ `https://plchldr.co/i/${res}?bg=F0F0F0&fc=111111&text=IMG`
3
+
4
+ export const highlights = [
5
+ // this should be returned form API when available
6
+ {
7
+ title: 'Test Box',
8
+ href: imagePlaceholderHref('50x50'),
9
+ },
10
+ {
11
+ title: 'Prince Harry',
12
+ href: imagePlaceholderHref('50x50'),
13
+ },
14
+ {
15
+ title: 'Meghan Markle',
16
+ href: imagePlaceholderHref('50x50'),
17
+ },
18
+ {
19
+ title: 'Royal Family',
20
+ href: imagePlaceholderHref('50x50'),
21
+ },
22
+ ]
23
+
24
+ export const relatedArticles = [
25
+ // this should be returned form API when available
26
+ {
27
+ title: 'Prince Harry',
28
+ tag: 'NEWS',
29
+ text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut a sodales leo. Cras egestas nisl libero, vitae viverra justo gravida quis.',
30
+ href: imagePlaceholderHref('70x50'),
31
+ },
32
+ {
33
+ title: 'Meghan Markle',
34
+ tag: 'SPORT',
35
+ text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut a sodales leo. Cras egestas nisl libero, vitae viverra justo gravida quis.',
36
+ href: imagePlaceholderHref('70x50'),
37
+ },
38
+ {
39
+ title: 'Royal Family',
40
+ tag: 'CULTURE',
41
+ text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut a sodales leo. Cras egestas nisl libero, vitae viverra justo gravida quis.',
42
+ href: imagePlaceholderHref('70x50'),
43
+ },
44
+ {
45
+ title: 'Royal',
46
+ tag: 'CORONAVIRUS',
47
+ text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut a sodales leo. Cras egestas nisl libero, vitae viverra justo gravida quis.',
48
+ href: imagePlaceholderHref('70x50'),
49
+ },
50
+ ]