diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml index f924d8f8f04..afd438e271a 100644 --- a/.github/workflows/production.yml +++ b/.github/workflows/production.yml @@ -23,7 +23,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v1 with: - node-version: 12 + node-version: 14 - name: Cache dependencies id: cache uses: actions/cache@v2 @@ -48,7 +48,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v2.1.2 with: - node-version: '12.x' + node-version: '14.x' - name: Set version env variable run: echo "GATSBY_DERIV_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index 3086a86c75a..1751dd80550 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -17,6 +17,7 @@ jobs: lint: timeout-minutes: 10 runs-on: ubuntu-latest + environment: staging steps: - name: Checkout 🛎️ @@ -25,7 +26,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v1 with: - node-version: 12 + node-version: 14 - name: Cache dependencies id: cache uses: actions/cache@v2 @@ -43,6 +44,7 @@ jobs: needs: lint timeout-minutes: 30 runs-on: ubuntu-latest + environment: staging steps: - name: Checkout 🛎️ uses: actions/checkout@v2.3.1 @@ -50,7 +52,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v2.1.2 with: - node-version: '12.x' + node-version: '14.x' - name: Cache dependencies uses: actions/cache@v2 diff --git a/.gitignore b/.gitignore index f0500ad8a5e..8c14990b80c 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,8 @@ typings/ # dotenv environment variables file .env +.env.development +.env.production # gatsby files .cache/ diff --git a/deriv.com.conf b/deriv.com.conf index 1b79363b9c0..f466dcc9678 100644 --- a/deriv.com.conf +++ b/deriv.com.conf @@ -29,6 +29,10 @@ server { return 301 https://$http_host/careers/; } + location ~* "^/([\w]{2}|zh-tw|zh-cn)/academy" { + return 301 https://$http_host/academy/; + } + location = /sw.js { add_header Cache-Control "public, max-age=0, must-revalidate"; } diff --git a/gatsby-config.js b/gatsby-config.js index 77b015a10bc..53628a7edbc 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -1,4 +1,7 @@ const language_config = require(`./i18n-config.js`) +require('dotenv').config({ + path: `.env.${process.env.NODE_ENV}`, +}) module.exports = { // pathPrefix: process.env.PATH_PREFIX || '/deriv-com/', // For non CNAME GH-pages deployment @@ -73,7 +76,7 @@ module.exports = { ], serialize: ({ site, allSitePage }) => allSitePage.edges.map((edge) => { - const ignore_localized_regex = /careers|besquare|livechat/ + const ignore_localized_regex = /careers|besquare|livechat|academy/ const path = edge.node.path let priority = 0.7 const languages = Object.keys(language_config) @@ -218,5 +221,17 @@ module.exports = { offset: -100, }, }, + { + resolve: '@directus/gatsby-source-directus', + options: { + url: 'https://cms.deriv.cloud', + auth: { + token: process.env.DIRECTUS_AUTH_TOKEN, + }, + dev: { + refresh: '5s', + }, + }, + }, ], } diff --git a/gatsby-node.js b/gatsby-node.js index 9aae24adfb8..113f69949f5 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -119,7 +119,7 @@ exports.onCreatePage = ({ page, actions }) => { const localized_path = is_default ? page.path : `${path}${page.path}` const is_production = process.env.GATSBY_ENV === 'production' const excluded_pages_regex = - /^[a-z-]+\/(careers|endpoint|offline-plugin-app-shell-fallback|besquare|livechat)\//g + /^[a-z-]+\/(careers|endpoint|offline-plugin-app-shell-fallback|besquare|livechat|academy)\//g if (is_production) { if (path === 'ach') return @@ -281,3 +281,37 @@ exports.onCreateWebpackConfig = ({ actions, getConfig }, { ...options }) => { }, }) } + +// TODO: To be updated to the new shape of the API of the new endpoint +exports.createPages = async ({ reporter, actions, graphql }) => { + const { createPage } = actions + const articleTemplate = path.resolve(__dirname, 'src/templates/article.js') + + // Query our published articles + const result = await graphql(` + query MyQuery { + directus { + blog(filter: { status: { _eq: "published" } }) { + id + slug + } + } + } + `) + + if (result.errors) { + reporter.panic(result.errors) + } + const blog = result.data.directus.blog + blog.forEach((blog_post) => { + createPage({ + path: `/academy/blog/posts/${blog_post.slug}`, + component: articleTemplate, + context: { + locale: 'en', + pathname: `/academy/blog/posts/${blog_post.slug}`, + slug: blog_post.slug, + }, + }) + }) +} diff --git a/package-lock.json b/package-lock.json index ba322453183..c7b132a870e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,33 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@apollo/client": { + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.3.20.tgz", + "integrity": "sha512-hS7UmBwJweudw/J3M0RAcusMHNiRuGqkRH6g91PM2ev8cXScIMdXr/++9jo7wD1nAITMCMF4HQQ3LFaw/Or0Bw==", + "requires": { + "@graphql-typed-document-node/core": "^3.0.0", + "@types/zen-observable": "^0.8.0", + "@wry/context": "^0.6.0", + "@wry/equality": "^0.5.0", + "fast-json-stable-stringify": "^2.0.0", + "graphql-tag": "^2.12.0", + "hoist-non-react-statics": "^3.3.2", + "optimism": "^0.16.0", + "prop-types": "^15.7.2", + "symbol-observable": "^4.0.0", + "ts-invariant": "^0.7.0", + "tslib": "^1.10.0", + "zen-observable": "^0.8.14" + }, + "dependencies": { + "symbol-observable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==" + } + } + }, "@ardatan/aggregate-error": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/@ardatan/aggregate-error/-/aggregate-error-0.0.6.tgz", @@ -2340,33 +2367,6 @@ "minimist": "^1.2.0" } }, - "@datadog/browser-core": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@datadog/browser-core/-/browser-core-2.14.0.tgz", - "integrity": "sha512-uwkuvv06WpIS4xm8ELU4+aMuc5FxrqW1GS22KbGcmJiYHxcUDrMkHO3wGwE2L2WhQ6rX9jtsZDWet8llx7WXCQ==", - "requires": { - "tslib": "^1.10.0" - } - }, - "@datadog/browser-rum": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@datadog/browser-rum/-/browser-rum-2.14.0.tgz", - "integrity": "sha512-sGgg6ncI7AbBS2fYDPmK98iNzaGIxGiINcbWYBTF5Ga/BhMgrECJzD09gu+UAKF/45TI4nyq5urva+viUGkLcw==", - "requires": { - "@datadog/browser-core": "2.14.0", - "@datadog/browser-rum-core": "2.14.0", - "tslib": "^1.10.0" - } - }, - "@datadog/browser-rum-core": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@datadog/browser-rum-core/-/browser-rum-core-2.14.0.tgz", - "integrity": "sha512-AJ1qOkat4e/xq+zr7khBsAIc8cz0FdrYk0Ecq+bc0u/EjBuUgvTE7JsZ4LcbklOOzXepXrw3B8grIUrfcQ/7zQ==", - "requires": { - "@datadog/browser-core": "2.14.0", - "tslib": "^1.10.0" - } - }, "@deriv/web-push-notifications": { "version": "3.21.1", "resolved": "https://registry.npmjs.org/@deriv/web-push-notifications/-/web-push-notifications-3.21.1.tgz", @@ -2381,6 +2381,445 @@ "whatwg-fetch": "3.0.0" } }, + "@directus/gatsby-source-directus": { + "version": "9.0.0-rc.95", + "resolved": "https://registry.npmjs.org/@directus/gatsby-source-directus/-/gatsby-source-directus-9.0.0-rc.95.tgz", + "integrity": "sha512-ZLIR/VU/WkQUcBsZJ0R1NX7AMUZuLfPRDN+UfQ0fJDRDqOD02Cls9VKdTAi+1Xq/9Xkztwpr0QgA4n9Wuo0auw==", + "requires": { + "@directus/sdk": "9.0.0-rc.95", + "chalk": "4.1.2", + "gatsby-source-filesystem": "3.14.0", + "gatsby-source-graphql": "3.14.0", + "invariant": "2.2.4", + "ms": "2.1.3" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", + "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@sindresorhus/is": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.2.0.tgz", + "integrity": "sha512-VkE3KLBmJwcCaVARtQpfuKcKv8gcBmUubrfHGF84dXuuW6jgsRYxPtzcIhPyK9WAPpRt2/xY6zkD9MnRaJzSyw==" + }, + "@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "requires": { + "defer-to-connect": "^2.0.0" + } + }, + "@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==" + }, + "cacheable-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "requires": { + "mimic-response": "^3.1.0" + } + }, + "defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "requires": { + "reusify": "^1.0.4" + } + }, + "file-type": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.3.tgz", + "integrity": "sha512-uVsl7iFhHSOY4bEONLlTK47iAHtNsFHWP5YE4xJfZ4rnX7S1Q3wce09XgqSC7E/xh8Ncv/be1lNoyprlUH/x6A==", + "requires": { + "readable-web-to-node-stream": "^3.0.0", + "strtok3": "^6.2.4", + "token-types": "^4.1.1" + } + }, + "fs-extra": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", + "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "gatsby-core-utils": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/gatsby-core-utils/-/gatsby-core-utils-2.14.0.tgz", + "integrity": "sha512-HDMb1XMqysup9raLYWB0wIQU568R9qPounF7iAwjf2esFUVV5mdBTvxEpune/7yG0RmwhNPhgrEZo2rBHeJf7A==", + "requires": { + "@babel/runtime": "^7.15.4", + "ci-info": "2.0.0", + "configstore": "^5.0.1", + "file-type": "^16.5.3", + "fs-extra": "^10.0.0", + "got": "^11.8.2", + "node-object-hash": "^2.3.9", + "proper-lockfile": "^4.1.2", + "tmp": "^0.2.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "got": { + "version": "11.8.2", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.2.tgz", + "integrity": "sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==", + "requires": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.1", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + } + } + } + }, + "gatsby-source-filesystem": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/gatsby-source-filesystem/-/gatsby-source-filesystem-3.14.0.tgz", + "integrity": "sha512-Gg5GGxiWXhjapWMYdXOGk7zp+ajYowS+xNmaDUkL1gH+IQLvE18XbvKh00B/HiFaHm4azJfS2QRrRI/mPTZX+w==", + "requires": { + "@babel/runtime": "^7.15.4", + "chokidar": "^3.5.2", + "fastq": "^1.11.1", + "file-type": "^16.5.3", + "fs-extra": "^10.0.0", + "gatsby-core-utils": "^2.14.0", + "got": "^9.6.0", + "md5-file": "^5.0.0", + "mime": "^2.5.2", + "pretty-bytes": "^5.4.1", + "progress": "^2.0.3", + "valid-url": "^1.0.9", + "xstate": "^4.14.0" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "dependencies": { + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + } + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "requires": { + "json-buffer": "3.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==" + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "requires": { + "lowercase-keys": "^1.0.0" + } + } + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "keyv": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", + "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", + "requires": { + "json-buffer": "3.0.1" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node-object-hash": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/node-object-hash/-/node-object-hash-2.3.10.tgz", + "integrity": "sha512-jY5dPJzw6NHd/KPSfPKJ+IHoFS81/tJ43r34ZeNMXGzCOM8jwQDCD12HYayKIB6MuznrnqIYy2e891NA2g0ibA==" + }, + "p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" + }, + "peek-readable": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.0.1.tgz", + "integrity": "sha512-7qmhptnR0WMSpxT5rMHG9bW/mYSR1uqaPFj2MHvT+y/aOUu6msJijpKt5SkTDKySwg65OWG2JwTMBlgcbwMHrQ==" + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "responselike": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "requires": { + "lowercase-keys": "^2.0.0" + } + }, + "strtok3": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.2.4.tgz", + "integrity": "sha512-GO8IcFF9GmFDvqduIspUBwCzCbqzegyVKIsSymcMgiZKeCfrN9SowtUoi8+b59WZMAjIzVZic/Ft97+pynR3Iw==", + "requires": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^4.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "token-types": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.1.1.tgz", + "integrity": "sha512-hD+QyuUAyI2spzsI0B7gf/jJ2ggR4RjkAo37j3StuePhApJUwcWDjnHDOFdIWYSwNR28H14hpwm4EI+V1Ted1w==", + "requires": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + } + } + }, + "@directus/sdk": { + "version": "9.0.0-rc.95", + "resolved": "https://registry.npmjs.org/@directus/sdk/-/sdk-9.0.0-rc.95.tgz", + "integrity": "sha512-Bv85tr2WvYZsK7IgbG6e9S4jmgt8jGOty6rX3+gm7k0NsQ8yGj2aVxuEyMabbGf3AHWftpCZqC31P7sm/TlfjA==", + "requires": { + "axios": "^0.21.1" + } + }, "@emotion/cache": { "version": "10.0.29", "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz", @@ -2657,6 +3096,35 @@ } } }, + "@graphql-tools/links": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/links/-/links-7.1.0.tgz", + "integrity": "sha512-8cJLs3ko0Zq0agJiFiHuAZ27OXbfgRF5JtVtIx8q2RfjVN0sss9QeetrTBjc2XfTj5HYZr6BHqqlyMMA4OXp7A==", + "requires": { + "@graphql-tools/delegate": "^7.1.0", + "@graphql-tools/utils": "^7.7.0", + "apollo-upload-client": "14.1.3", + "cross-fetch": "3.1.2", + "form-data": "4.0.0", + "is-promise": "4.0.0", + "tslib": "~2.1.0" + }, + "dependencies": { + "cross-fetch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.2.tgz", + "integrity": "sha512-+JhD65rDNqLbGmB3Gzs3HrEKC0aQnD+XA3SY6RjgkF88jV2q5cTc5+CwxlS3sdmLk98gpPt5CF9XRnPdlxZe6w==", + "requires": { + "node-fetch": "2.6.1" + } + }, + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" + } + } + }, "@graphql-tools/load": { "version": "6.2.8", "resolved": "https://registry.npmjs.org/@graphql-tools/load/-/load-6.2.8.tgz", @@ -2796,6 +3264,11 @@ } } }, + "@graphql-typed-document-node/core": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.0.tgz", + "integrity": "sha512-wYn6r8zVZyQJ6rQaALBEln5B1pzxb9shV5Ef97kTvn6yVGrqyXVnDqnU24MXnFubR+rZjBY9NWuxX3FB2sTsjg==" + }, "@hapi/address": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", @@ -10444,6 +10917,11 @@ "resolved": "https://registry.npmjs.org/@types/yoga-layout/-/yoga-layout-1.9.2.tgz", "integrity": "sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw==" }, + "@types/zen-observable": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.3.tgz", + "integrity": "sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw==" + }, "@typescript-eslint/eslint-plugin": { "version": "4.27.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.27.0.tgz", @@ -10811,6 +11289,51 @@ "@xtuc/long": "4.2.2" } }, + "@wry/context": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.6.0.tgz", + "integrity": "sha512-sAgendOXR8dM7stJw3FusRxFHF/ZinU0lffsA2YTyyIOfic86JX02qlPqPVqJNZJPAxFt+2EE8bvq6ZlS0Kf+Q==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + } + } + }, + "@wry/equality": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.5.1.tgz", + "integrity": "sha512-FZKbdpbcVcbDxQrKcaBClNsQaMg9nof1RKM7mReJe5DKUzM5u8S7T+PqwNqvib5O2j2xxF1R4p5O3+b6baTrbw==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + } + } + }, + "@wry/trie": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.3.0.tgz", + "integrity": "sha512-Yw1akIogPhAT6XPYsRHlZZIS0tIGmAl9EYXHi2scf7LPKKqdqmow/Hu4kEqP2cJR3EjaU/9L0ZlAjFf3hFxmug==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + } + } + }, "@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -11028,6 +11551,96 @@ "picomatch": "^2.0.4" } }, + "apollo-link": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.14.tgz", + "integrity": "sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg==", + "requires": { + "apollo-utilities": "^1.3.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3", + "zen-observable-ts": "^0.8.21" + }, + "dependencies": { + "ts-invariant": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", + "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", + "requires": { + "tslib": "^1.9.3" + } + } + } + }, + "apollo-link-http": { + "version": "1.5.17", + "resolved": "https://registry.npmjs.org/apollo-link-http/-/apollo-link-http-1.5.17.tgz", + "integrity": "sha512-uWcqAotbwDEU/9+Dm9e1/clO7hTB2kQ/94JYcGouBVLjoKmTeJTUPQKcJGpPwUjZcSqgYicbFqQSoJIW0yrFvg==", + "requires": { + "apollo-link": "^1.2.14", + "apollo-link-http-common": "^0.2.16", + "tslib": "^1.9.3" + } + }, + "apollo-link-http-common": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/apollo-link-http-common/-/apollo-link-http-common-0.2.16.tgz", + "integrity": "sha512-2tIhOIrnaF4UbQHf7kjeQA/EmSorB7+HyJIIrUjJOKBgnXwuexi8aMecRlqTIDWcyVXCeqLhUnztMa6bOH/jTg==", + "requires": { + "apollo-link": "^1.2.14", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3" + }, + "dependencies": { + "ts-invariant": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", + "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", + "requires": { + "tslib": "^1.9.3" + } + } + } + }, + "apollo-upload-client": { + "version": "14.1.3", + "resolved": "https://registry.npmjs.org/apollo-upload-client/-/apollo-upload-client-14.1.3.tgz", + "integrity": "sha512-X2T+7pHk5lcaaWnvP9h2tuAAMCzOW6/9juedQ0ZuGp3Ufl81BpDISlCs0o6u29wBV0RRT/QpMU2gbP+3FCfVpQ==", + "requires": { + "@apollo/client": "^3.2.5", + "@babel/runtime": "^7.12.5", + "extract-files": "^9.0.0" + } + }, + "apollo-utilities": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.4.tgz", + "integrity": "sha512-pk2hiWrCXMAy2fRPwEyhvka+mqwzeP60Jr1tRYi5xru+3ko94HI9o6lK0CT33/w4RDlxWchmdhDCrvdr+pHCig==", + "requires": { + "@wry/equality": "^0.1.2", + "fast-json-stable-stringify": "^2.0.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.10.0" + }, + "dependencies": { + "@wry/equality": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.1.11.tgz", + "integrity": "sha512-mwEVBDUVODlsQQ5dfuLUS5/Tf7jqUKyhKYHmVi4fPB6bDMOfWvUPJmKgS1Z7Za/sOI3vzWt4+O7yCiL/70MogA==", + "requires": { + "tslib": "^1.9.3" + } + }, + "ts-invariant": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", + "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", + "requires": { + "tslib": "^1.9.3" + } + } + } + }, "app-root-dir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/app-root-dir/-/app-root-dir-1.0.2.tgz", @@ -19396,6 +20009,11 @@ } } }, + "gatsby-plugin-page-progress": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/gatsby-plugin-page-progress/-/gatsby-plugin-page-progress-2.2.1.tgz", + "integrity": "sha512-ItrUyMQOyhMjtEsJ+IKQVKNJ7qa+8E4P16mQSPd1fsxTUcmEn5vNT47pCVnePjT5MuxarFRTbvy1mcHARgp0ew==" + }, "gatsby-plugin-react-helmet": { "version": "4.7.1", "resolved": "https://registry.npmjs.org/gatsby-plugin-react-helmet/-/gatsby-plugin-react-helmet-4.7.1.tgz", @@ -20412,6 +21030,33 @@ } } }, + "gatsby-source-graphql": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/gatsby-source-graphql/-/gatsby-source-graphql-3.14.0.tgz", + "integrity": "sha512-Tsi3CvczlwWaDpDlCTc4GgZC8hlNfEL3/0wGCQ61ygW7/2B77hvnCZxR1HlYjUKRn7S19T4G5hi4ZykPi3PFBw==", + "requires": { + "@babel/runtime": "^7.15.4", + "@graphql-tools/links": "^7.1.0", + "@graphql-tools/utils": "^7.7.3", + "@graphql-tools/wrap": "^7.0.8", + "apollo-link": "1.2.14", + "apollo-link-http": "^1.5.17", + "dataloader": "^2.0.0", + "invariant": "^2.2.4", + "node-fetch": "^2.6.1", + "uuid": "3.4.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", + "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + } + } + }, "gatsby-telemetry": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/gatsby-telemetry/-/gatsby-telemetry-2.7.1.tgz", @@ -21128,6 +21773,21 @@ "iterall": "^1.3.0" } }, + "graphql-tag": { + "version": "2.12.5", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.5.tgz", + "integrity": "sha512-5xNhP4063d16Pz3HBtKprutsPrmHZi5IdUGOWRxA2B6VF7BIRGOHZ5WQvDmJXZuPcBg7rYwaFxvQYjqkSdR3TQ==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + } + } + }, "graphql-type-json": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/graphql-type-json/-/graphql-type-json-0.3.2.tgz", @@ -21863,6 +22523,22 @@ } } }, + "http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "dependencies": { + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" + } + } + }, "https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", @@ -25622,6 +26298,15 @@ } } }, + "optimism": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.16.1.tgz", + "integrity": "sha512-64i+Uw3otrndfq5kaoGNoY7pvOhSsjFEN4bdEFh80MWVk/dbgJfMv7VFDeCT8LxNAlEVhQmdVEbfE7X2nWNIIg==", + "requires": { + "@wry/context": "^0.6.0", + "@wry/trie": "^0.3.0" + } + }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -28532,6 +29217,11 @@ "path-parse": "^1.0.6" } }, + "resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + }, "resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", @@ -31434,6 +32124,21 @@ "integrity": "sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w==", "dev": true }, + "ts-invariant": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.7.5.tgz", + "integrity": "sha512-qfVyqTYWEqADMtncLqwpUdMjMSXnsqOeqGtj1LeJNFDjz8oqZ1YxLEp29YCOq65z0LgEiERqQ8ThVjnfibJNpg==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, "ts-node": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", @@ -33524,6 +34229,20 @@ } } }, + "zen-observable": { + "version": "0.8.15", + "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", + "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==" + }, + "zen-observable-ts": { + "version": "0.8.21", + "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.21.tgz", + "integrity": "sha512-Yj3yXweRc8LdRMrCC8nIc4kkjWecPAUVh0TI0OUrWXx6aX790vLcDlWca6I4vsyCGH3LpWxq0dJRcMOFoVqmeg==", + "requires": { + "tslib": "^1.9.3", + "zen-observable": "^0.8.0" + } + }, "zwitch": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", diff --git a/package.json b/package.json index c9a942a0f82..2ec3647f4ec 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "dependencies": { "@artsy/fresnel": "^1.7.0", "@deriv/web-push-notifications": "^3.21.1", + "@directus/gatsby-source-directus": "^9.0.0-rc.83", "@livechat/customer-sdk": "^3.0.0", "@loadable/component": "^5.15.0", "@svgr/webpack": "^5.5.0", @@ -22,6 +23,7 @@ "gatsby-plugin-image": "^1.7.1", "gatsby-plugin-manifest": "^3.7.1", "gatsby-plugin-nprogress": "^3.7.1", + "gatsby-plugin-page-progress": "^2.2.1", "gatsby-plugin-react-helmet": "^4.7.1", "gatsby-plugin-robots-txt": "^1.6.2", "gatsby-plugin-sharp": "^3.7.1", @@ -108,7 +110,6 @@ "url": "https://github.com/binary-com/deriv-com/issues" }, "engines": { - "npm": ">=6.9.0", - "node": ">=12.3.0" + "npm": ">=6.9.0" } } diff --git a/src/common/constants.js b/src/common/constants.js index 962209f5f73..3ed0a69d314 100644 --- a/src/common/constants.js +++ b/src/common/constants.js @@ -82,6 +82,7 @@ export const localized_link_url = Object.freeze({ mt5: deriv_mt5_app_url, smart_trader: smarttrader_url, zoho: zoho_url, + domain_full_url: domain_full_url, 'terms_and_conditions/#clients': domain_full_url, 'terms_and_conditions/#business-partners': domain_full_url, }) @@ -102,3 +103,4 @@ export const linkedin_url_career = 'https://www.linkedin.com/company/derivdotcom export const twitter_non_eu_url = 'https://twitter.com/derivdotcom/' export const twitter_uk_url = 'https://www.twitter.com/deriv_uk/' export const twitter_eu_url = 'https://www.twitter.com/deriv_eu/' +export const cms_assets_end_point = 'https://cms.deriv.cloud/assets/' diff --git a/src/common/utility.js b/src/common/utility.js index 96e9e61d517..13cbf1edbd0 100644 --- a/src/common/utility.js +++ b/src/common/utility.js @@ -2,6 +2,7 @@ import { navigate } from 'gatsby' import Cookies from 'js-cookie' import extend from 'extend' import { + cms_assets_end_point, deriv_cookie_domain, deriv_app_languages, live_chat_redirection_link, @@ -245,6 +246,57 @@ export const redirectOpenLiveChatBox = (is_redirect) => { } } +export const convertDate = (date) => { + const newdate = new Date(date) + return ( + newdate.toLocaleString('en', { day: 'numeric' }) + + ' ' + + newdate.toLocaleString('en', { month: 'short' }) + + ' ' + + newdate.toLocaleString('en', { year: 'numeric' }) + ) +} + +// CMS Related Utilities +export const getAssetUrl = (id) => `${cms_assets_end_point}${id}` + +export const getVideoObject = (video_data) => { + const { + published_date, + video_file, + video_thumbnail, + video_title, + video_duration, + video_description, + featured, + tags, + } = video_data + const { id: video_id } = video_file + const { id: thumbnail_id, title: alt } = video_thumbnail + + return { + published_date, + thumbnail_img: getAssetUrl(thumbnail_id), + thumbnail_img_alt: alt, + video_title, + video_description, + video_url: getAssetUrl(video_id), + video_duration, + featured, + types: tags.map((t) => t.tags_id.tag_name), + } +} + +// remove spaces before appending "..." on truncated strings +const getLimit = (input, limit) => { + if (input[limit - 1] === ' ') { + return limit - 1 + } + return limit +} + +export const truncateString = (input, limit) => + input.length > limit ? `${input.substring(0, getLimit(input, limit))}...` : input // Function which returns sub path to the specific trading platform const supported_platforms = ['mt5', 'bot', 'derivx'] export const redirectToTradingPlatform = () => diff --git a/src/common/validation.js b/src/common/validation.js index e1d495fb8be..188d342528b 100644 --- a/src/common/validation.js +++ b/src/common/validation.js @@ -16,6 +16,13 @@ const validation = { return null } }, + name: (input, message) => { + if (!input) { + return message ? message : localize('Name is required') + } else { + return null + } + }, required: (input, message) => { if (!input) { return message ? message : localize('This field is required') diff --git a/src/components/custom/_agreement-label.js b/src/components/custom/_agreement-label.js index 19533c0e36e..77f236aab64 100644 --- a/src/components/custom/_agreement-label.js +++ b/src/components/custom/_agreement-label.js @@ -2,18 +2,22 @@ import React from 'react' import PropTypes from 'prop-types' import styled from 'styled-components' import { Checkbox, LocalizedLinkText } from 'components/elements' -import { Localize } from 'components/localization' +import { Localize, localize } from 'components/localization' import device from 'themes/device.js' const CheckboxSpan = styled.span` - font-size: var(--text-size-xs); + font-size: 14px; color: ${(props) => (props.color ? props.color : 'black')}; @media ${device.tabletL} { - font-size: 1.75rem; + font-size: 12px; } ` - -const AgreementLabel = ({ handleChangeCheckbox, isChecked, color }) => { +const AgreementLabel = ({ + handleChangeCheckbox, + isChecked, + color, + link_text = localize('I agree to the <0>terms and conditions'), +}) => { const handleChange = (event) => { handleChangeCheckbox(event) } @@ -41,8 +45,8 @@ const AgreementLabel = ({ handleChangeCheckbox, isChecked, color }) => { /> ( /> } - title={localize('Blog')} + title={localize('Academy')} onClick={onClick} - to="" - type="blog" - external="true" - target="_blank" - rel="noopener noreferrer" + to="/academy/" /> ) diff --git a/src/components/elements/background-image.js b/src/components/elements/background-image.js index 3ed453f1ad2..2cb52c627c2 100644 --- a/src/components/elements/background-image.js +++ b/src/components/elements/background-image.js @@ -14,12 +14,12 @@ const StyledBackground = styled(BackgroundImage)` } ` -export const Background = ({ children, data, style, dark, ...props }) => { +export const Background = ({ children, data, fluid, style, dark, ...props }) => { const image = getImage(data) const bgImage = convertToBgImage(image) return ( - + {children} ) @@ -30,6 +30,7 @@ Background.propTypes = { children: PropTypes.node, dark: PropTypes.string, data: PropTypes.object, + fluid: PropTypes.array, img_name: PropTypes.string, style: PropTypes.object, } diff --git a/src/components/elements/default-tab.js b/src/components/elements/default-tab.js index ce145024fed..2e9299c311f 100644 --- a/src/components/elements/default-tab.js +++ b/src/components/elements/default-tab.js @@ -3,9 +3,9 @@ import PropTypes from 'prop-types' import styled, { css } from 'styled-components' import { Text } from './typography' import { Flex } from 'components/containers' +import { useTabStateQuery } from 'components/hooks/use-tab-state-query' import { useTabState } from 'components/hooks/use-tab-state' import device from 'themes/device' - const TabContent = styled.div` flex: 1; width: 100%; @@ -25,6 +25,14 @@ const TabButton = styled.button` border: none; border-bottom: 2px solid var(--color-grey-2); white-space: nowrap; + + @media ${device.laptopM} { + width: ${(props) => + props.mobile_tab_button_underline_length + ? props.mobile_tab_button_underline_length + : 'unset'}; + } + ${(props) => props.selected && css` @@ -45,7 +53,7 @@ const TabButton = styled.button` const TabList = styled.div` display: flex; width: 100%; - justify-content: center; + justify-content: ${(props) => (props.jc ? props.jc : 'center')}; position: relative; overflow: auto; @@ -57,7 +65,10 @@ const TabList = styled.div` scrollbar-width: none; @media ${device.mobileL} { - justify-content: space-between; + justify-content: ${(props) => (props.jc_mobileL ? props.jc_mobileL : 'space-between')}; + } + @media ${device.laptopM} { + justify-content: ${(props) => (props.jc_laptopM ? props.jc_laptopM : 'center')}; } ` @@ -65,7 +76,7 @@ const LineDivider = styled.div` bottom: 0; position: absolute; height: 2px; - width: 100%; + width: ${(props) => (props.line_divider_length ? props.line_divider_length : '100%')}; background: var(--color-grey-2); z-index: 1; ` @@ -78,8 +89,6 @@ const Content = styled.div` const TextWrapper = styled(Text)` text-align: center; font-size: var(--text-size-m); - color: var(--color-black); - @media ${device.tabletS} { font-size: ${({ font_size }) => font_size ?? 'var(--text-size-sm)'}; } @@ -98,9 +107,21 @@ TabPanel.propTypes = { children: PropTypes.node, } -const Tabs = ({ children, route_from, tab_list }) => { +const Tabs = ({ + children, + route_from, + tab_list, + jc, + jc_mobileL, + jc_laptopM, + line_divider_length, + mobile_tab_button_underline_length, + has_no_query, +}) => { const [selected_tab, setSelectedTab] = useState(0) - const [active_tab, setActiveTab] = useTabState(tab_list) + const [active_tab, setActiveTab] = has_no_query + ? useTabState(tab_list) + : useTabStateQuery(tab_list) useEffect(() => { setSelectedTab(tab_list.indexOf(active_tab)) @@ -108,20 +129,27 @@ const Tabs = ({ children, route_from, tab_list }) => { return ( - + {React.Children.map(children, ({ props: { label } }, index) => ( setActiveTab(tab_list[index])} + mobile_tab_button_underline_length={mobile_tab_button_underline_length} > {label} ))} - + @@ -137,6 +165,12 @@ Tabs.Panel = TabPanel Tabs.propTypes = { children: PropTypes.node, + has_no_query: PropTypes.bool, + jc: PropTypes.string, + jc_laptopM: PropTypes.string, + jc_mobileL: PropTypes.string, + line_divider_length: PropTypes.string, + mobile_tab_button_underline_length: PropTypes.string, route_from: PropTypes.string, tab_list: PropTypes.array, } diff --git a/src/components/elements/off-canvas-menu.js b/src/components/elements/off-canvas-menu.js index e9dce9a8419..76537ee31f6 100644 --- a/src/components/elements/off-canvas-menu.js +++ b/src/components/elements/off-canvas-menu.js @@ -451,18 +451,11 @@ export const OffCanvasMenuWrapper = (props) => { - +
- {localize('Blog')} + {localize('Academy')} diff --git a/src/components/elements/side-tab.js b/src/components/elements/side-tab.js index 63007c33521..a6f52095f4d 100644 --- a/src/components/elements/side-tab.js +++ b/src/components/elements/side-tab.js @@ -6,7 +6,7 @@ import device, { size } from 'themes/device' import { getWindowWidth } from 'common/utility' import { Box } from 'components/containers' import { Desktop } from 'components/containers/show' -import { useTabState } from 'components/hooks/use-tab-state' +import { useTabStateQuery } from 'components/hooks/use-tab-state-query' const StyledSideTab = styled(Box)` padding: 0; @@ -114,7 +114,7 @@ const Tab = ({ active_tab, font_size, label, line_height, mobile, onClick, opaci const getTabs = (children) => children.map((child) => child.props.label) const SideTab = ({ children, font_size, is_sticky, line_height, opacity, tab_header }) => { - const [active_tab, setActiveTab] = useTabState(getTabs(children)) + const [active_tab, setActiveTab] = useTabStateQuery(getTabs(children)) const [is_menu, setMenu] = useState(false) const Tabs = (props) => { diff --git a/src/components/hooks/use-tab-state-query.js b/src/components/hooks/use-tab-state-query.js new file mode 100644 index 00000000000..51c6c072323 --- /dev/null +++ b/src/components/hooks/use-tab-state-query.js @@ -0,0 +1,43 @@ +import { useState, useEffect } from 'react' +import { + checkElemInArray, + getLocationHash, + isBrowser, + routeBack, + scrollTop, + setLocationHash, +} from 'common/utility' + +export const useTabStateQuery = (tab_list) => { + const [active_tab, setActiveTab] = useState( + getLocationHash() && checkElemInArray(tab_list, getLocationHash()) + ? getLocationHash() + : tab_list[0], + ) + + useEffect(() => { + if (!getLocationHash() || !checkElemInArray(tab_list, getLocationHash())) { + setLocationHash(active_tab) + } else { + setActiveTab(getLocationHash()) + scrollTop() + } + }, []) + + useEffect(() => { + if (getLocationHash() !== active_tab && isBrowser()) { + setLocationHash(active_tab) + } + }, [active_tab]) + + useEffect(() => { + if (getLocationHash() !== active_tab && checkElemInArray(tab_list, getLocationHash())) { + setActiveTab(getLocationHash()) + scrollTop() + } else if (!checkElemInArray(tab_list, getLocationHash())) { + routeBack() + } + }, [getLocationHash()]) + + return [active_tab, setActiveTab] +} diff --git a/src/components/hooks/use-tab-state.js b/src/components/hooks/use-tab-state.js index 8ae646dc443..e417f1b99ae 100644 --- a/src/components/hooks/use-tab-state.js +++ b/src/components/hooks/use-tab-state.js @@ -1,43 +1,7 @@ -import { useState, useEffect } from 'react' -import { - checkElemInArray, - getLocationHash, - isBrowser, - routeBack, - scrollTop, - setLocationHash, -} from 'common/utility' +import { useState } from 'react' export const useTabState = (tab_list) => { - const [active_tab, setActiveTab] = useState( - getLocationHash() && checkElemInArray(tab_list, getLocationHash()) - ? getLocationHash() - : tab_list[0], - ) - - useEffect(() => { - if (!getLocationHash() || !checkElemInArray(tab_list, getLocationHash())) { - setLocationHash(active_tab) - } else { - setActiveTab(getLocationHash()) - scrollTop() - } - }, []) - - useEffect(() => { - if (getLocationHash() !== active_tab && isBrowser()) { - setLocationHash(active_tab) - } - }, [active_tab]) - - useEffect(() => { - if (getLocationHash() !== active_tab && checkElemInArray(tab_list, getLocationHash())) { - setActiveTab(getLocationHash()) - scrollTop() - } else if (!checkElemInArray(tab_list, getLocationHash())) { - routeBack() - } - }, [getLocationHash()]) + const [active_tab, setActiveTab] = useState(tab_list[0]) return [active_tab, setActiveTab] } diff --git a/src/components/layout/footer.js b/src/components/layout/footer.js index e1d23610031..0e9a72f6831 100644 --- a/src/components/layout/footer.js +++ b/src/components/layout/footer.js @@ -6,6 +6,7 @@ import { DefaultFooter, FooterGrid } from './footer/common/style.js' import LogoSection from './footer/logo' import MainLinksSection from './footer/main-links' import DisclaimerSection from './footer/disclaimer' +import DisclaimerSectionAcademy from './footer/disclaimer-academy' import CopyrightSection from './footer/copyright' import BottomSocialSection from './footer/bottom-social-wrapper' import AdditionalEUSection from './footer/additional-eu' @@ -23,7 +24,7 @@ const mobile_accordion_header = { const mobile_accordion_header_about = Object.assign({}, mobile_accordion_header) -const Footer = ({ type, is_ppc, is_ppc_redirect }) => { +const Footer = ({ type, is_ppc, is_ppc_redirect, academy }) => { const { show_cookie_banner } = React.useContext(LocationContext) const { is_eu_country } = React.useContext(DerivStore) mobile_accordion_header_about.borderTop = 'none' @@ -38,7 +39,7 @@ const Footer = ({ type, is_ppc, is_ppc_redirect }) => { is_ppc_redirect={is_ppc_redirect} is_eu_country={is_eu_country} /> - + {academy ? : } @@ -49,6 +50,7 @@ const Footer = ({ type, is_ppc, is_ppc_redirect }) => { } Footer.propTypes = { + academy: PropTypes.bool, is_ppc: PropTypes.bool, is_ppc_redirect: PropTypes.bool, type: PropTypes.string, diff --git a/src/components/layout/footer/common/style.js b/src/components/layout/footer/common/style.js index 3d6db429cff..467a9ea0321 100644 --- a/src/components/layout/footer/common/style.js +++ b/src/components/layout/footer/common/style.js @@ -106,6 +106,13 @@ export const Link = styled(StyledLink)` font-size: var(--text-size-xs); line-height: 1.5; ` +export const AcademyWrapper = styled.div` + color: var(--color-red-1); + font-size: var(--text-size-xs); + line-height: 1.5; + margin-top: 10px; +` + export const LinkWrapper = styled.div` margin-top: ${(props) => (props.first_child == 'true' ? '0.8rem' : '1.6rem')}; diff --git a/src/components/layout/footer/disclaimer-academy.js b/src/components/layout/footer/disclaimer-academy.js new file mode 100644 index 00000000000..9c551bfede9 --- /dev/null +++ b/src/components/layout/footer/disclaimer-academy.js @@ -0,0 +1,106 @@ +import React from 'react' +import { + DisclaimerWrapper, + DisclaimerParagraph, + RiskWarning, + StaticAsset, + BoldLink, +} from './common/style.js' +import { Localize, localize } from 'components/localization' + +const DisclaimerSectionAcademy = () => { + return ( + <> + + + , + ]} + /> + + + , + , + ]} + /> + + + , + , + ]} + /> + + + {localize( + "This website's services are not available in certain countries, including the USA, Canada, and Hong Kong, or to persons below 18.", + )} + + + {localize( + 'The information contained in this academy is for educational purposes only and is not intended as financial or investment advice.', + )} + + + + + + + + + + + + + , + , + ]} + /> + + + + + ) +} + +export default DisclaimerSectionAcademy diff --git a/src/components/layout/footer/disclaimer.js b/src/components/layout/footer/disclaimer.js index 170a4f1fb11..beba414fd92 100644 --- a/src/components/layout/footer/disclaimer.js +++ b/src/components/layout/footer/disclaimer.js @@ -104,7 +104,7 @@ const DisclaimerSection = () => { {localize( - "This website's services are not made available in certain countries, including the USA, Canada, and Hong Kong, or to persons below 18.", + "This website's services are not available in certain countries, including the USA, Canada, and Hong Kong, or to persons below 18.", )} diff --git a/src/components/layout/footer/main-links.js b/src/components/layout/footer/main-links.js index 1b1be11ee0b..2c82a08e884 100644 --- a/src/components/layout/footer/main-links.js +++ b/src/components/layout/footer/main-links.js @@ -186,15 +186,7 @@ const MainLinksSection = ({ is_ppc, is_ppc_redirect, is_eu_country }) => { - - {localize('Blog')} - + {localize('Academy')}
diff --git a/src/components/layout/layout.js b/src/components/layout/layout.js index 7f61a364548..d351c71f69e 100644 --- a/src/components/layout/layout.js +++ b/src/components/layout/layout.js @@ -170,6 +170,10 @@ const Layout = ({ let Navigation = <> let FooterNav = <> switch (type) { + case 'academy': + Navigation =