From 44003f3e44e12d08b3fdd51abce6f7edd9aab4d3 Mon Sep 17 00:00:00 2001 From: Daniel Dimitrov Date: Wed, 18 Sep 2024 15:55:49 +0200 Subject: [PATCH] fix: cypress tests failing due to incorrect terms version --- cypress.config.js | 23 +++++++++++- .../sendfunds_connected_wallet.cy.js | 2 +- cypress/e2e/happypath/sendfunds_queue_1.cy.js | 2 +- cypress/e2e/happypath/sendfunds_relay.cy.js | 2 +- .../happypath/tx_history_filter_hp_2.cy.js | 2 +- cypress/e2e/regression/tokens.cy.js | 2 +- cypress/e2e/safe-apps/apps_list.cy.js | 2 +- .../e2e/safe-apps/drain_account.spec.cy.js | 2 +- cypress/e2e/safe-apps/preview_drawer.cy.js | 2 +- cypress/e2e/safe-apps/safe_permissions.cy.js | 2 +- cypress/e2e/safe-apps/tx-builder.spec.cy.js | 2 +- cypress/e2e/safe-apps/tx_modal.cy.js | 2 +- cypress/support/constants.js | 4 +- cypress/support/localstorage_data.js | 15 +++++++- next-env.d.ts | 2 +- package.json | 1 + .../sidebar/SidebarFooter/index.tsx | 5 +-- src/pages/terms.tsx | 1 - src/services/analytics/useGtm.ts | 2 +- src/store/cookiesAndTermsSlice.ts | 2 +- yarn.lock | 37 ++++++++++++++++++- 21 files changed, 91 insertions(+), 23 deletions(-) diff --git a/cypress.config.js b/cypress.config.js index b476d90a2d..3907ddefe4 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -1,9 +1,13 @@ import { defineConfig } from 'cypress' import 'dotenv/config' import * as fs from 'fs' - +import path, { dirname } from 'path' +import { fileURLToPath } from 'url'; +import matter from 'gray-matter' import { configureVisualRegression } from 'cypress-visual-regression' +const __dirname = dirname(fileURLToPath(import.meta.url)) + export default defineConfig({ projectId: 'exhdra', trashAssetsBeforeRuns: true, @@ -18,6 +22,21 @@ export default defineConfig({ e2e: { screenshotsFolder: './cypress/snapshots/actual', setupNodeEvents(on, config) { + + // Read and parse the terms Markdown file + try { + const filePath = path.resolve(__dirname, './src/markdown/terms/terms.md') + + const content = fs.readFileSync(filePath, 'utf8') + const parsed = matter(content) + const frontmatter = parsed.data + + // Set Cookie term version on the cypress env - this way we can access it in the tests + config.env.CURRENT_COOKIE_TERMS_VERSION = frontmatter.version + } catch (error) { + console.error('Error reading or parsing terms.md file:', error) + } + configureVisualRegression(on), on('task', { log(message) { @@ -34,6 +53,8 @@ export default defineConfig({ } } }) + + return config }, env: { ...process.env, diff --git a/cypress/e2e/happypath/sendfunds_connected_wallet.cy.js b/cypress/e2e/happypath/sendfunds_connected_wallet.cy.js index 21fea79984..f0236a53a0 100644 --- a/cypress/e2e/happypath/sendfunds_connected_wallet.cy.js +++ b/cypress/e2e/happypath/sendfunds_connected_wallet.cy.js @@ -48,7 +48,7 @@ function visit(url) { describe('Send funds with connected signer happy path tests', { defaultCommandTimeout: 60000 }, () => { before(async () => { cy.clearLocalStorage().then(() => { - main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies_1_1, ls.cookies.acceptedCookies) + main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies, ls.cookies.acceptedCookies) main.addToLocalStorage( constants.localStorageKeys.SAFE_v2__tokenlist_onboarding, ls.cookies.acceptedTokenListOnboarding, diff --git a/cypress/e2e/happypath/sendfunds_queue_1.cy.js b/cypress/e2e/happypath/sendfunds_queue_1.cy.js index d7cbd3f490..b1f6e1bd42 100644 --- a/cypress/e2e/happypath/sendfunds_queue_1.cy.js +++ b/cypress/e2e/happypath/sendfunds_queue_1.cy.js @@ -54,7 +54,7 @@ function executeTransactionFlow(fromSafe) { describe('Send funds from queue happy path tests 1', () => { before(async () => { cy.clearLocalStorage().then(() => { - main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies_1_1, ls.cookies.acceptedCookies) + main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies, ls.cookies.acceptedCookies) main.addToLocalStorage( constants.localStorageKeys.SAFE_v2__tokenlist_onboarding, ls.cookies.acceptedTokenListOnboarding, diff --git a/cypress/e2e/happypath/sendfunds_relay.cy.js b/cypress/e2e/happypath/sendfunds_relay.cy.js index e32a05f45a..4aaf53648f 100644 --- a/cypress/e2e/happypath/sendfunds_relay.cy.js +++ b/cypress/e2e/happypath/sendfunds_relay.cy.js @@ -49,7 +49,7 @@ function visit(url) { describe('Send funds with relay happy path tests', { defaultCommandTimeout: 300000 }, () => { before(async () => { cy.clearLocalStorage().then(() => { - main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies_1_1, ls.cookies.acceptedCookies) + main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies, ls.cookies.acceptedCookies) main.addToLocalStorage( constants.localStorageKeys.SAFE_v2__tokenlist_onboarding, ls.cookies.acceptedTokenListOnboarding, diff --git a/cypress/e2e/happypath/tx_history_filter_hp_2.cy.js b/cypress/e2e/happypath/tx_history_filter_hp_2.cy.js index cd7154b31a..39c322ccee 100644 --- a/cypress/e2e/happypath/tx_history_filter_hp_2.cy.js +++ b/cypress/e2e/happypath/tx_history_filter_hp_2.cy.js @@ -9,7 +9,7 @@ let staticSafes = [] describe('Tx history happy path tests 2', () => { before(async () => { cy.clearLocalStorage().then(() => { - main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies_1_1, ls.cookies.acceptedCookies) + main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies, ls.cookies.acceptedCookies) main.addToLocalStorage( constants.localStorageKeys.SAFE_v2__tokenlist_onboarding, ls.cookies.acceptedTokenListOnboarding, diff --git a/cypress/e2e/regression/tokens.cy.js b/cypress/e2e/regression/tokens.cy.js index 24fbe4c663..44580c8c2e 100644 --- a/cypress/e2e/regression/tokens.cy.js +++ b/cypress/e2e/regression/tokens.cy.js @@ -19,7 +19,7 @@ describe('Tokens tests', () => { beforeEach(() => { cy.visit(constants.BALANCE_URL + staticSafes.SEP_STATIC_SAFE_2) cy.clearLocalStorage().then(() => { - main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies_1_1, ls.cookies.acceptedCookies) + main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies, ls.cookies.acceptedCookies) main.addToLocalStorage( constants.localStorageKeys.SAFE_v2__tokenlist_onboarding, ls.cookies.acceptedTokenListOnboarding, diff --git a/cypress/e2e/safe-apps/apps_list.cy.js b/cypress/e2e/safe-apps/apps_list.cy.js index eb98aea2d4..46e3e44a9b 100644 --- a/cypress/e2e/safe-apps/apps_list.cy.js +++ b/cypress/e2e/safe-apps/apps_list.cy.js @@ -16,7 +16,7 @@ describe('Safe Apps list tests', () => { beforeEach(() => { cy.clearLocalStorage().then(() => { - main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies_1_1, ls.cookies.acceptedCookies) + main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies, ls.cookies.acceptedCookies) }) cy.visit(`${constants.appsUrl}?safe=${staticSafes.SEP_STATIC_SAFE_1}`, { failOnStatusCode: false, diff --git a/cypress/e2e/safe-apps/drain_account.spec.cy.js b/cypress/e2e/safe-apps/drain_account.spec.cy.js index 293fc78a26..749e34094a 100644 --- a/cypress/e2e/safe-apps/drain_account.spec.cy.js +++ b/cypress/e2e/safe-apps/drain_account.spec.cy.js @@ -13,7 +13,7 @@ describe('Drain Account tests', () => { before(async () => { safeAppSafes = await getSafes(CATEGORIES.safeapps) cy.clearLocalStorage().then(() => { - main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies_1_1, ls.cookies.acceptedCookies) + main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies, ls.cookies.acceptedCookies) main.addToLocalStorage( constants.localStorageKeys.SAFE_v2__SafeApps__infoModal, ls.appPermissions(constants.safeTestAppurl).infoModalAccepted, diff --git a/cypress/e2e/safe-apps/preview_drawer.cy.js b/cypress/e2e/safe-apps/preview_drawer.cy.js index 86018f1dd7..debbe9b314 100644 --- a/cypress/e2e/safe-apps/preview_drawer.cy.js +++ b/cypress/e2e/safe-apps/preview_drawer.cy.js @@ -10,7 +10,7 @@ describe('Preview drawer tests', () => { before(async () => { staticSafes = await getSafes(CATEGORIES.static) cy.clearLocalStorage().then(() => { - main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies_1_1, ls.cookies.acceptedCookies) + main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies, ls.cookies.acceptedCookies) }) }) diff --git a/cypress/e2e/safe-apps/safe_permissions.cy.js b/cypress/e2e/safe-apps/safe_permissions.cy.js index 037bd374a3..8aa4cd31b3 100644 --- a/cypress/e2e/safe-apps/safe_permissions.cy.js +++ b/cypress/e2e/safe-apps/safe_permissions.cy.js @@ -6,7 +6,7 @@ import * as ls from '../../support/localstorage_data.js' describe('Safe permissions system tests', () => { before(async () => { cy.clearLocalStorage().then(() => { - main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies_1_1, ls.cookies.acceptedCookies) + main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies, ls.cookies.acceptedCookies) }) }) diff --git a/cypress/e2e/safe-apps/tx-builder.spec.cy.js b/cypress/e2e/safe-apps/tx-builder.spec.cy.js index 5ced7d6123..699518dfa5 100644 --- a/cypress/e2e/safe-apps/tx-builder.spec.cy.js +++ b/cypress/e2e/safe-apps/tx-builder.spec.cy.js @@ -24,7 +24,7 @@ describe.skip('Transaction Builder tests', { defaultCommandTimeout: 20000 }, () cy.clearLocalStorage() cy.clearCookies() cy.window().then((win) => { - win.localStorage.setItem(constants.localStorageKeys.SAFE_v2_cookies_1_1, ls.cookies.acceptedCookies) + win.localStorage.setItem(constants.localStorageKeys.SAFE_v2_cookies, ls.cookies.acceptedCookies) win.localStorage.setItem( constants.localStorageKeys.SAFE_v2__SafeApps__infoModal, ls.appPermissions(constants.safeTestAppurl).infoModalAccepted, diff --git a/cypress/e2e/safe-apps/tx_modal.cy.js b/cypress/e2e/safe-apps/tx_modal.cy.js index d2b9078157..003e147a38 100644 --- a/cypress/e2e/safe-apps/tx_modal.cy.js +++ b/cypress/e2e/safe-apps/tx_modal.cy.js @@ -10,7 +10,7 @@ const confirmTx = 'Confirm transaction' describe('Transaction modal tests', () => { before(async () => { cy.clearLocalStorage().then(() => { - main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies_1_1, ls.cookies.acceptedCookies) + main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies, ls.cookies.acceptedCookies) main.addToLocalStorage( constants.localStorageKeys.SAFE_v2__SafeApps__infoModal, ls.appPermissions(constants.safeTestAppurl).infoModalAccepted, diff --git a/cypress/support/constants.js b/cypress/support/constants.js index 6b5f294dab..b49298c6b3 100644 --- a/cypress/support/constants.js +++ b/cypress/support/constants.js @@ -228,13 +228,15 @@ export const addresBookContacts = { }, } +export const CURRENT_COOKIE_TERMS_VERSION = Cypress.env('CURRENT_COOKIE_TERMS_VERSION') + export const localStorageKeys = { SAFE_v2__addressBook: 'SAFE_v2__addressBook', SAFE_v2__batch: 'SAFE_v2__batch', SAFE_v2__settings: 'SAFE_v2__settings', SAFE_v2__addedSafes: 'SAFE_v2__addedSafes', SAFE_v2__safeApps: 'SAFE_v2__safeApps', - SAFE_v2_cookies_1_1: 'SAFE_v2__cookies_terms_v1.1', + SAFE_v2_cookies: 'SAFE_v2__cookies_terms', SAFE_v2__tokenlist_onboarding: 'SAFE_v2__tokenlist_onboarding', SAFE_v2__customSafeApps_11155111: 'SAFE_v2__customSafeApps-11155111', SAFE_v2__SafeApps__browserPermissions: 'SAFE_v2__SafeApps__browserPermissions', diff --git a/cypress/support/localstorage_data.js b/cypress/support/localstorage_data.js index 9407a1fb30..7b0ac24805 100644 --- a/cypress/support/localstorage_data.js +++ b/cypress/support/localstorage_data.js @@ -1,4 +1,15 @@ /* eslint-disable */ + +import { CURRENT_COOKIE_TERMS_VERSION } from './constants.js' + +const cookieState = { + necessary: true, + updates: true, + analytics: true, + terms: true, + termsVersion: CURRENT_COOKIE_TERMS_VERSION +} + export const batchData = { entry0: { 11155111: { @@ -379,7 +390,7 @@ export const addressBookData = { '0xc2F3645bfd395516d1a18CA6ad9298299d328C01': 'Safe 27', }, }, - cookies: { necessary: true, updates: true, analytics: true }, + cookies: cookieState, } export const safeSettings = { @@ -673,7 +684,7 @@ export const appPermissions = (url) => ({ }) export const cookies = { - acceptedCookies: { necessary: true, updates: true, analytics: true }, + acceptedCookies: cookieState, acceptedTokenListOnboarding: true, } diff --git a/next-env.d.ts b/next-env.d.ts index 4f11a03dc6..a4a7b3f5cf 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/basic-features/typescript for more information. +// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information. diff --git a/package.json b/package.json index 8ccc2f72b2..c621ae0681 100644 --- a/package.json +++ b/package.json @@ -145,6 +145,7 @@ "eslint-plugin-storybook": "^0.8.0", "eslint-plugin-unused-imports": "^2.0.0", "fake-indexeddb": "^4.0.2", + "gray-matter": "^4.0.3", "husky": "^9.0.11", "jest": "^29.6.2", "jest-environment-jsdom": "^29.6.2", diff --git a/src/components/sidebar/SidebarFooter/index.tsx b/src/components/sidebar/SidebarFooter/index.tsx index 191bdc646e..d6d1876c2c 100644 --- a/src/components/sidebar/SidebarFooter/index.tsx +++ b/src/components/sidebar/SidebarFooter/index.tsx @@ -1,5 +1,5 @@ import type { ReactElement } from 'react' -import { useCallback, useEffect } from 'react' +import { useEffect } from 'react' import { SidebarList, @@ -9,7 +9,7 @@ import { } from '@/components/sidebar/SidebarList' import { BEAMER_SELECTOR, loadBeamer } from '@/services/beamer' import { useAppDispatch, useAppSelector } from '@/store' -import { selectCookies, CookieAndTermType, hasConsentFor } from '@/store/cookiesAndTermsSlice' +import { CookieAndTermType, hasConsentFor } from '@/store/cookiesAndTermsSlice' import { openCookieBanner } from '@/store/popupSlice' import BeamerIcon from '@/public/images/sidebar/whats-new.svg' import HelpCenterIcon from '@/public/images/sidebar/help-center.svg' @@ -25,7 +25,6 @@ const SidebarFooter = (): ReactElement => { const chain = useCurrentChain() const hasBeamerConsent = useAppSelector((state) => hasConsentFor(state, CookieAndTermType.UPDATES)) - useEffect(() => { // Initialise Beamer when consent was previously given if (hasBeamerConsent && chain?.shortName) { diff --git a/src/pages/terms.tsx b/src/pages/terms.tsx index b896d114ad..b8dffc0304 100644 --- a/src/pages/terms.tsx +++ b/src/pages/terms.tsx @@ -26,7 +26,6 @@ const overrideComponents: MDXComponents = { a: CustomLink, } - const Terms: NextPage = () => { return ( <> diff --git a/src/services/analytics/useGtm.ts b/src/services/analytics/useGtm.ts index 90e09be208..91fcffda1b 100644 --- a/src/services/analytics/useGtm.ts +++ b/src/services/analytics/useGtm.ts @@ -16,7 +16,7 @@ import { } from '@/services/analytics/gtm' import { spindlInit, spindlAttribute } from './spindl' import { useAppSelector } from '@/store' -import { CookieAndTermType, hasConsentFor, selectCookies } from '@/store/cookiesAndTermsSlice' +import { CookieAndTermType, hasConsentFor } from '@/store/cookiesAndTermsSlice' import useChainId from '@/hooks/useChainId' import { useRouter } from 'next/router' import { AppRoutes } from '@/config/routes' diff --git a/src/store/cookiesAndTermsSlice.ts b/src/store/cookiesAndTermsSlice.ts index 799518e2ee..7f9c2a6410 100644 --- a/src/store/cookiesAndTermsSlice.ts +++ b/src/store/cookiesAndTermsSlice.ts @@ -27,7 +27,7 @@ export const cookiesAndTermsInitialState: CookiesAndTermsState = { } export const cookiesAndTermsSlice = createSlice({ - name: `cookies_terms_v1.2`, + name: `cookies_terms`, initialState: cookiesAndTermsInitialState, reducers: { saveCookieAndTermConsent: (_, { payload }: PayloadAction) => payload, diff --git a/yarn.lock b/yarn.lock index 2e0ba2c21e..d79626d37c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10715,6 +10715,13 @@ ext@^1.1.2: dependencies: type "^2.7.2" +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== + dependencies: + is-extendable "^0.1.0" + extend@^3.0.0, extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -11433,6 +11440,16 @@ graphemer@^1.4.0: resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== +gray-matter@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.3.tgz#e893c064825de73ea1f5f7d88c7a9f7274288798" + integrity sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q== + dependencies: + js-yaml "^3.13.1" + kind-of "^6.0.2" + section-matter "^1.0.0" + strip-bom-string "^1.0.0" + gzip-size@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" @@ -12163,6 +12180,11 @@ is-docker@^2.0.0: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== +is-extendable@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -13224,7 +13246,7 @@ keyvaluestorage-interface@^1.0.0: resolved "https://registry.yarnpkg.com/keyvaluestorage-interface/-/keyvaluestorage-interface-1.0.0.tgz#13ebdf71f5284ad54be94bd1ad9ed79adad515ff" integrity sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g== -kind-of@^6.0.3: +kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== @@ -16734,6 +16756,14 @@ secp256k1@^4.0.0, secp256k1@^4.0.1: node-addon-api "^2.0.0" node-gyp-build "^4.2.0" +section-matter@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/section-matter/-/section-matter-1.0.0.tgz#e9041953506780ec01d59f292a19c7b850b84167" + integrity sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA== + dependencies: + extend-shallow "^2.0.1" + kind-of "^6.0.0" + "semver@2 || 3 || 4 || 5", semver@^5.6.0: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" @@ -17341,6 +17371,11 @@ strip-ansi@^7.0.1, strip-ansi@^7.1.0: dependencies: ansi-regex "^6.0.1" +strip-bom-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" + integrity sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g== + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"