diff --git a/packages/ui-extensions-dev-console/package.json b/packages/ui-extensions-dev-console/package.json index dba538503e0..8fe1ad363d8 100644 --- a/packages/ui-extensions-dev-console/package.json +++ b/packages/ui-extensions-dev-console/package.json @@ -13,7 +13,6 @@ }, "dependencies": { "@shopify/polaris-icons": "^8.0.0", - "@shopify/react-i18n": "^7.5.0", "@shopify/ui-extensions-server-kit": "5.4.0", "copy-to-clipboard": "^3.3.3", "qrcode.react": "^4.2.0", diff --git a/packages/ui-extensions-dev-console/src/App.tsx b/packages/ui-extensions-dev-console/src/App.tsx index 2ef8902066b..d94d2667338 100644 --- a/packages/ui-extensions-dev-console/src/App.tsx +++ b/packages/ui-extensions-dev-console/src/App.tsx @@ -4,7 +4,6 @@ import {Toast} from '@/foundation/Toast' import {Theme} from '@/foundation/Theme' import {ModalContainer} from '@/foundation/ModalContainer' import {ExtensionServerProvider, isValidSurface} from '@shopify/ui-extensions-server-kit' -import {I18nContext, I18nManager} from '@shopify/react-i18n' import React from 'react' function getConnectionUrl() { @@ -25,26 +24,16 @@ const extensionServerOptions = { surface: isValidSurface(surface) ? surface : undefined, } -const i18nManager = new I18nManager({ - locale: 'en', - onError(error) { - // eslint-disable-next-line no-console - console.error(error) - }, -}) - function App() { return ( - - - - - - - - - + + + + + + + ) } diff --git a/packages/ui-extensions-dev-console/src/components/Modal/components/Header/components/CloseButton/CloseButton.tsx b/packages/ui-extensions-dev-console/src/components/Modal/components/Header/components/CloseButton/CloseButton.tsx index b284da64113..2c5c09af238 100644 --- a/packages/ui-extensions-dev-console/src/components/Modal/components/Header/components/CloseButton/CloseButton.tsx +++ b/packages/ui-extensions-dev-console/src/components/Modal/components/Header/components/CloseButton/CloseButton.tsx @@ -1,8 +1,8 @@ import en from './translations/en.json' import {IconButton} from '@/components/IconButton/IconButton' +import {useI18n} from '@/hooks/useI18n' import React from 'react' import {XIcon} from '@shopify/polaris-icons' -import {useI18n} from '@shopify/react-i18n' interface CloseButtonProps { pressed?: boolean diff --git a/packages/ui-extensions-dev-console/src/foundation/Layout/Layout.tsx b/packages/ui-extensions-dev-console/src/foundation/Layout/Layout.tsx index 021c1aa65f7..8afaebb8022 100644 --- a/packages/ui-extensions-dev-console/src/foundation/Layout/Layout.tsx +++ b/packages/ui-extensions-dev-console/src/foundation/Layout/Layout.tsx @@ -1,9 +1,9 @@ import en from './translations/en.json' import * as styles from './Layout.module.scss' import {isAppPreview} from '@/utilities/app-preview' +import {useI18n} from '@/hooks/useI18n' import React from 'react' import {WrenchIcon} from '@shopify/polaris-icons' -import {useI18n} from '@shopify/react-i18n' interface Props { children: React.ReactNode diff --git a/packages/ui-extensions-dev-console/src/hooks/useI18n.ts b/packages/ui-extensions-dev-console/src/hooks/useI18n.ts new file mode 100644 index 00000000000..8033058a199 --- /dev/null +++ b/packages/ui-extensions-dev-console/src/hooks/useI18n.ts @@ -0,0 +1,62 @@ +import React from 'react' + +type TranslationDictionary = Record +type Replacements = Record + +interface I18nTranslator { + translate(key: string, replacements?: Replacements): React.ReactNode +} + +function getNestedValue(obj: TranslationDictionary, key: string): string | undefined { + const result = key.split('.').reduce((current, segment) => { + if (current != null && typeof current === 'object') { + return (current as TranslationDictionary)[segment] + } + return undefined + }, obj) + return typeof result === 'string' ? result : undefined +} + +function interpolate(template: string, replacements?: Replacements): React.ReactNode { + if (!replacements) return template + + const hasReactNodes = Object.values(replacements).some((value) => React.isValidElement(value)) + + if (!hasReactNodes) { + return template.replace(/\{(\w+)\}/g, (match, key: string) => + key in replacements ? String(replacements[key]) : match, + ) + } + + const parts: React.ReactNode[] = [] + const regex = /\{(\w+)\}/g + let lastIndex = 0 + let match: RegExpExecArray | null + + while ((match = regex.exec(template)) !== null) { + if (match.index > lastIndex) { + parts.push(template.slice(lastIndex, match.index)) + } + const key = match[1] + parts.push(key in replacements ? replacements[key] : match[0]) + lastIndex = regex.lastIndex + } + + if (lastIndex < template.length) { + parts.push(template.slice(lastIndex)) + } + + return React.createElement(React.Fragment, null, ...parts) +} + +export function useI18n({fallback}: {id: string; fallback: TranslationDictionary}): [I18nTranslator] { + return [ + { + translate(key: string, replacements?: Replacements) { + const template = getNestedValue(fallback, key) + if (template == null) return key + return interpolate(template, replacements) + }, + }, + ] +} diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/Extensions.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/Extensions.tsx index f0ecc3439a1..ae3bb68617d 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/Extensions.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/Extensions.tsx @@ -8,8 +8,8 @@ import {useApp} from './hooks/useApp' import {isEmbedded} from '@/utilities/embedded' import {isAppPreview} from '@/utilities/app-preview' +import {useI18n} from '@/hooks/useI18n' import React from 'react' -import {useI18n} from '@shopify/react-i18n' export function Extensions() { const [i18n] = useI18n({ diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/AppHomeRow/AppHomeRow.test.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/AppHomeRow/AppHomeRow.test.tsx index 657b90ba29d..4ebd65c4bb6 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/AppHomeRow/AppHomeRow.test.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/AppHomeRow/AppHomeRow.test.tsx @@ -1,8 +1,6 @@ import {AppHomeRow} from '.' -import en from './translations/en.json' import {PreviewLink, QRCodeModal} from '..' import {DefaultProviders} from 'tests/DefaultProviders' -import {mockI18n} from 'tests/mock-i18n' import {Button} from '@/components' import React from 'react' @@ -19,8 +17,6 @@ vi.mock('@/components', () => ({ Button: (props: any) => props.children, })) -mockI18n(en) - describe('', () => { const defaultState = { app: {url: 'mock.url', title: 'Mock App Title'}, diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/AppHomeRow/AppHomeRow.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/AppHomeRow/AppHomeRow.tsx index 372263caec2..e07331f0dc0 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/AppHomeRow/AppHomeRow.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/AppHomeRow/AppHomeRow.tsx @@ -5,10 +5,9 @@ import {useApp} from '../../hooks/useApp' import {useExtensionServerOptions} from '../../hooks/useExtensionServerOptions.js' import {Button} from '@/components' +import {useI18n} from '@/hooks/useI18n' import React, {useState} from 'react' -import {useI18n} from '@shopify/react-i18n' - export function AppHomeRow() { const [showModal, setShowModal] = useState(false) const [i18n] = useI18n({ diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/ExtensionRow.test.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/ExtensionRow.test.tsx index 33f4ac94bc0..abf19f75713 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/ExtensionRow.test.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/ExtensionRow.test.tsx @@ -1,8 +1,6 @@ import {ExtensionRow} from '.' -import en from './translations/en.json' import {QRCodeModal} from '..' import {DefaultProviders} from 'tests/DefaultProviders' -import {mockI18n} from 'tests/mock-i18n' import {Button} from '@/components' import React from 'react' @@ -19,8 +17,6 @@ vi.mock('..', () => ({ Status: () => null, })) -mockI18n(en) - describe('', () => { const legacyAdminExtension = mockExtension({type: 'product_subscription', surface: 'admin'}) const legacyPosExtension = mockExtension({type: 'pos_ui_extension', surface: 'point_of_sale'}) diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/ExtensionRow.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/ExtensionRow.tsx index af65c52f23c..1226470dfac 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/ExtensionRow.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/ExtensionRow.tsx @@ -4,8 +4,8 @@ import * as styles from './ExtensionRow.module.scss' import {QRCodeModal, Row, Status} from '..' import {useExtension} from '../../hooks/useExtension' import {Button} from '@/components/Button' +import {useI18n} from '@/hooks/useI18n' import React, {useState} from 'react' -import {useI18n} from '@shopify/react-i18n' import {ExtensionPayload, ExtensionPoint, isUIExtension} from '@shopify/ui-extensions-server-kit' interface Props { diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/components/PreviewLinks/PreviewLinks.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/components/PreviewLinks/PreviewLinks.tsx index 04cdd4e103a..0ddeec12819 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/components/PreviewLinks/PreviewLinks.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/components/PreviewLinks/PreviewLinks.tsx @@ -2,9 +2,9 @@ import en from './translations/en.json' import * as styles from './PreviewLinks.module.scss' import {NotApplicable, PreviewLink} from '../../..' import {classNames} from '@/utilities/css' +import {useI18n} from '@/hooks/useI18n' import React from 'react' import {ExtensionPayload} from '@shopify/ui-extensions-server-kit' -import {useI18n} from '@shopify/react-i18n' interface Props { extension: ExtensionPayload diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/PreviewLink/PreviewLink.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/PreviewLink/PreviewLink.tsx index 85e222e265e..0a77188365a 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/PreviewLink/PreviewLink.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/PreviewLink/PreviewLink.tsx @@ -3,8 +3,8 @@ import * as styles from './PreviewLink.module.scss' import {useNavigate} from '../../hooks/useNavigate.js' import {IconButton} from '@/components/IconButton' import {isEmbedded} from '@/utilities/embedded' +import {useI18n} from '@/hooks/useI18n' import React from 'react' -import {useI18n} from '@shopify/react-i18n' import {ClipboardIcon} from '@shopify/polaris-icons' import {toast} from 'react-toastify' diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/QRCodeModal/QRCodeModal.test.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/QRCodeModal/QRCodeModal.test.tsx index af72e14b0f8..d01f63c21c8 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/QRCodeModal/QRCodeModal.test.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/QRCodeModal/QRCodeModal.test.tsx @@ -1,6 +1,4 @@ import {QRCodeModal} from './QRCodeModal' -import en from './translations/en.json' -import {mockI18n} from 'tests/mock-i18n' import {DefaultProviders} from 'tests/DefaultProviders' import {Modal} from '@/components/Modal' import React from 'react' @@ -12,8 +10,6 @@ vi.spyOn(HTMLCanvasElement.prototype, 'getContext').mockReturnValue(null) vi.mock('@/components/Modal', () => ({Modal: (props: any) => props.children})) -mockI18n(en) - describe('QRCodeModal', () => { const defaultProps = { onClose: vi.fn(), diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/QRCodeModal/QRCodeModal.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/QRCodeModal/QRCodeModal.tsx index 8175d5bf330..b307592b48d 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/QRCodeModal/QRCodeModal.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/QRCodeModal/QRCodeModal.tsx @@ -3,8 +3,8 @@ import en from './translations/en.json' import {useApp} from '../../hooks/useApp' import {Modal, ModalProps} from '@/components/Modal' import {IconButton} from '@/components/IconButton' +import {useI18n} from '@/hooks/useI18n' import React, {useCallback, useMemo} from 'react' -import {useI18n} from '@shopify/react-i18n' import copyToClipboard from 'copy-to-clipboard' import {QRCodeCanvas as QRCode} from 'qrcode.react' import {toast} from 'react-toastify' diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/Status/Status.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/Status/Status.tsx index ffd9ce15905..e7ea4fe1d20 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/Status/Status.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/Status/Status.tsx @@ -1,8 +1,8 @@ import en from './translations/en.json' import * as styles from './Status.module.scss' import {Tooltip} from '@/components/Tooltip' +import {useI18n} from '@/hooks/useI18n' import React from 'react' -import {useI18n} from '@shopify/react-i18n' import {Status as StatusProp} from '@shopify/ui-extensions-server-kit' interface Props { diff --git a/packages/ui-extensions-dev-console/tests/DefaultProviders.ts b/packages/ui-extensions-dev-console/tests/DefaultProviders.ts index bd58044d366..ebc45214da0 100644 --- a/packages/ui-extensions-dev-console/tests/DefaultProviders.ts +++ b/packages/ui-extensions-dev-console/tests/DefaultProviders.ts @@ -1,5 +1,4 @@ -import {MockI18nProvider} from './MockI18nProvider' import {MockExtensionServerProvider} from '@shopify/ui-extensions-server-kit/testing' import {withProviders} from '@shopify/ui-extensions-test-utils' -export const DefaultProviders = withProviders(MockExtensionServerProvider, MockI18nProvider) +export const DefaultProviders = withProviders(MockExtensionServerProvider) diff --git a/packages/ui-extensions-dev-console/tests/MockI18nProvider.tsx b/packages/ui-extensions-dev-console/tests/MockI18nProvider.tsx deleted file mode 100644 index 8ffff30518e..00000000000 --- a/packages/ui-extensions-dev-console/tests/MockI18nProvider.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react' -import {I18nContext, I18nManager} from '@shopify/react-i18n' - -export function MockI18nProvider({children}: React.PropsWithChildren>) { - const i18nManager = new I18nManager({ - locale: 'en', - onError(error) { - // eslint-disable-next-line no-console - console.log(error) - }, - }) - - return {children} -} diff --git a/packages/ui-extensions-dev-console/tests/mock-i18n.ts b/packages/ui-extensions-dev-console/tests/mock-i18n.ts deleted file mode 100644 index 59669bdbb58..00000000000 --- a/packages/ui-extensions-dev-console/tests/mock-i18n.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {CurrencyCode, I18n, I18nDetails, TranslationDictionary} from '@shopify/react-i18n' - -const defaultI18nDetails = { - locale: 'en', - currency: CurrencyCode.Usd, - country: 'CA', - timezone: 'UTC', -} - -export function mockI18n( - translations?: TranslationDictionary | TranslationDictionary[], - details: Partial = {}, -) { - return new I18n(Array.isArray(translations) ? translations : (translations && [translations]) || [], { - ...defaultI18nDetails, - ...details, - }) -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 39a23811bf0..610c5178558 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -714,9 +714,6 @@ importers: '@shopify/polaris-icons': specifier: ^8.0.0 version: 8.11.1(react@18.3.1) - '@shopify/react-i18n': - specifier: ^7.5.0 - version: 7.14.0(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@shopify/ui-extensions-server-kit': specifier: 5.4.0 version: link:../ui-extensions-server-kit @@ -3614,11 +3611,6 @@ packages: vite: optional: true - '@shopify/dates@2.1.1': - resolution: {integrity: sha512-ut05iQ/MVRzdEIfIv/DV64qx1qm+NkEhWlCPQxMKiISJj/PpfnMutrSgeu8j6VGnxpCK9lQXjEaDEnhq5NEzqA==} - engines: {node: '>=18.12.0'} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - '@shopify/eslint-plugin-cli@file:packages/eslint-plugin-cli': resolution: {directory: packages/eslint-plugin-cli, type: directory} peerDependencies: @@ -3629,28 +3621,13 @@ packages: peerDependencies: eslint: ^9.27.0 - '@shopify/function-enhancers@3.1.0': - resolution: {integrity: sha512-4nkPRFw+d8oaJlevO+fpdFuFj70MnpP+liShGGKEa76LaH4mVenIpcQPf+vEF4of27AMQCbefyMHNlHJX0Wtag==} - engines: {node: '>=18.12.0'} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - '@shopify/generate-docs@0.15.6': resolution: {integrity: sha512-4p6c2Xlt5TVAACM/YD6dcEioKeCpHwv5n65TOIGQaFhRUsA3yRFrbD+8G2TSfeW60QIZchzvRQ7xwYjljGajlA==} hasBin: true - '@shopify/i18n@2.1.0': - resolution: {integrity: sha512-fNCmdriHz4fs8pPFehsIhf8jJGmiiJUqqdQJhn5+ri30RmVsxL14xtuiDMoHWtH0CKwE4j2aq2XBnfby0My9Ew==} - engines: {node: '>=18.12.0'} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - '@shopify/liquid-html-parser@2.9.0': resolution: {integrity: sha512-bkI4tLbU47YUxpgbMa9fgeJjFEMvRNEFL644Yk0ZKo5H1IRzU4pPyCQ6PkGvb0JJnt7OZ+RDGvb6ZLCnAR2Z/A==} - '@shopify/name@1.3.0': - resolution: {integrity: sha512-gAz0WcPXSHXyBr4Kr8pQdsxMU4vnOi0piJouraunlABTuxiRw3zdEIrO/YXhgmxjmArYdoNSbNkhzq6AbOHEvA==} - engines: {node: '>=18.12.0'} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - '@shopify/oxygen-cli@4.6.18': resolution: {integrity: sha512-LxJUkHL1Oudxy712XHTBd1se3Gq2w+/FYVyj5rAmyiNSFfbXD3zHWHjB5zbeeFjbRIPhbJW3OgRjJgn7VIo8EA==} engines: {node: '>=18.12.0'} @@ -3680,28 +3657,6 @@ packages: react: ^18.0.0 react-dom: ^18.0.0 - '@shopify/react-effect@5.2.0': - resolution: {integrity: sha512-FFNceV2N57GuBOBUmBnGrmpe46heYujaLPBXFscejKr8mzTPDkTIKctmhVVePyLg3hDgZbxQDjPsAl7qOOE3/Q==} - engines: {node: '>=18.12.0'} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - peerDependencies: - react: '>=18.0.0 <19.0.0' - react-dom: '>=16.8.0 <19.0.0' - - '@shopify/react-hooks@4.1.2': - resolution: {integrity: sha512-F5WWZ7t2qd0i+ALCFbdQ6v5TG+6jUZ/N/dTWLd7w56uteO2H6a91KfwUWClffPVfch0qqlHG84F8t4pOMj8/Gg==} - engines: {node: '>=18.12.0'} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - peerDependencies: - react: '>=18.0.0 <19.0.0' - - '@shopify/react-i18n@7.14.0': - resolution: {integrity: sha512-mdY5uER8KIqUOOFwV37Q90fW+lW+ApWHE7zcgFYxInR4PDjtGNNejRvRGY3rn1JcsHEz7kdcymd02ay4kvincA==} - engines: {node: '>=18.12.0'} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - peerDependencies: - react: '>=18.0.0 <19.0.0' - '@shopify/react-testing@5.4.0': resolution: {integrity: sha512-qlu6NUnMK9Mq/1lu6MIvZMSKT/AtXnHGyuu148DMshVF8d7E5+JDtgTVGeKKV8nnjL5cly4K91dyPVt6fHq5yA==} engines: {node: '>=18.12.0'} @@ -4062,11 +4017,6 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - '@types/hoist-non-react-statics@3.3.7': - resolution: {integrity: sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==} - peerDependencies: - '@types/react': 18.3.12 - '@types/http-cache-semantics@4.2.0': resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} @@ -6335,9 +6285,6 @@ packages: headers-polyfill@4.0.3: resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} - hoist-non-react-statics@3.3.2: - resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} - hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -7027,9 +6974,6 @@ packages: lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - lodash.clonedeep@4.5.0: - resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} - lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} @@ -8577,9 +8521,6 @@ packages: string-env-interpolation@1.0.1: resolution: {integrity: sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==} - string-hash@1.1.3: - resolution: {integrity: sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==} - string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -13180,10 +13121,6 @@ snapshots: - react - react-dom - '@shopify/dates@2.1.1': - dependencies: - '@shopify/function-enhancers': 3.1.0 - '@shopify/eslint-plugin-cli@file:packages/eslint-plugin-cli(@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(prettier@3.8.1)(typescript@5.9.3)(vitest@3.2.4(@types/node@18.19.70)(jiti@2.6.1)(jsdom@28.1.0)(msw@2.12.10(@types/node@18.19.70)(typescript@5.9.3))(sass@1.97.3)(yaml@2.8.2))': dependencies: '@babel/core': 7.27.4 @@ -13254,23 +13191,17 @@ snapshots: - supports-color - typescript - '@shopify/function-enhancers@3.1.0': {} - '@shopify/generate-docs@0.15.6': dependencies: '@types/react': 18.3.12 globby: 11.1.0 typescript: 5.9.3 - '@shopify/i18n@2.1.0': {} - '@shopify/liquid-html-parser@2.9.0': dependencies: line-column: 1.0.2 ohm-js: 17.5.0 - '@shopify/name@1.3.0': {} - '@shopify/oxygen-cli@4.6.18(@oclif/core@3.26.5)(@shopify/cli-kit@packages+cli-kit)(graphql@16.10.0)': dependencies: '@bugsnag/core': 8.8.0 @@ -13307,40 +13238,6 @@ snapshots: react-fast-compare: 3.2.2 react-transition-group: 4.4.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@shopify/react-effect@5.2.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - - '@shopify/react-hooks@4.1.2(react@18.3.1)': - dependencies: - react: 18.3.1 - - '@shopify/react-i18n@7.14.0(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@shopify/dates': 2.1.1 - '@shopify/function-enhancers': 3.1.0 - '@shopify/i18n': 2.1.0 - '@shopify/name': 1.3.0 - '@shopify/react-effect': 5.2.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@shopify/react-hooks': 4.1.2(react@18.3.1) - '@shopify/useful-types': 5.3.0 - '@types/hoist-non-react-statics': 3.3.7(@types/react@18.3.12) - change-case: 4.1.2 - glob: 7.2.3 - hoist-non-react-statics: 3.3.2 - lodash.clonedeep: 4.5.0 - lodash.merge: 4.6.2 - react: 18.3.1 - string-hash: 1.1.3 - strip-json-comments: 3.1.1 - optionalDependencies: - '@babel/template': 7.28.6 - fs-extra: 9.1.0 - transitivePeerDependencies: - - '@types/react' - - react-dom - '@shopify/react-testing@5.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@shopify/useful-types': 5.3.0 @@ -13895,11 +13792,6 @@ snapshots: dependencies: '@types/unist': 3.0.3 - '@types/hoist-non-react-statics@3.3.7(@types/react@18.3.12)': - dependencies: - '@types/react': 18.3.12 - hoist-non-react-statics: 3.3.2 - '@types/http-cache-semantics@4.2.0': {} '@types/http-errors@2.0.5': {} @@ -16554,10 +16446,6 @@ snapshots: headers-polyfill@4.0.3: {} - hoist-non-react-statics@3.3.2: - dependencies: - react-is: 16.13.1 - hosted-git-info@2.8.9: {} hosted-git-info@7.0.2: @@ -17309,8 +17197,6 @@ snapshots: lodash.camelcase@4.3.0: {} - lodash.clonedeep@4.5.0: {} - lodash.debounce@4.0.8: {} lodash.defaults@4.2.0: {} @@ -18989,8 +18875,6 @@ snapshots: string-env-interpolation@1.0.1: {} - string-hash@1.1.3: {} - string-width@4.2.3: dependencies: emoji-regex: 8.0.0