diff --git a/bin/bundling/esbuild-plugin-graphiql-imports.js b/bin/bundling/esbuild-plugin-graphiql-imports.js index e8d91797670..bd201644236 100644 --- a/bin/bundling/esbuild-plugin-graphiql-imports.js +++ b/bin/bundling/esbuild-plugin-graphiql-imports.js @@ -1,23 +1,47 @@ import { readFile } from 'fs/promises' +const createRequireStatement = /const require = createRequire\(import\.meta\.url\);?\r?\n/ + +const resolveGraphiQLAssetHelper = `function resolveGraphiQLAsset(asset) { + const {existsSync} = require('node:fs') + const {dirname, join, parse} = require('node:path') + const {fileURLToPath} = require('node:url') + + for ( + let directory = dirname(fileURLToPath(import.meta.url)); + directory !== parse(directory).root; + directory = dirname(directory) + ) { + const candidate = join(directory, 'assets', 'graphiql', asset) + if (existsSync(candidate)) return candidate + } + + return require.resolve(\`@shopify/cli-kit/assets/graphiql/\${asset}\`) +} +` + const GraphiQLImportsPlugin = { name: 'GraphiQLImportsPlugin', setup(build) { // GraphiQL uses require.resolve with paths that won't work with esbuild // We need to replace them with valid paths - // graphiql/server.ts uses require.resolve('@shopify/app/assets/...'). The bundled CLI does not ship - // @shopify/app as a dependency; assets are copied to dist/assets. Rewrite to paths relative to bundled - // command files under dist/cli/commands/** (e.g. app/dev.js -> ../../../assets/graphiql/...). + // graphiql/server.ts uses require.resolve('@shopify/cli-kit/assets/...'). The bundled CLI does not ship + // @shopify/cli-kit as a dependency; assets are copied to dist/assets. Rewrite to a resolver that works whether + // esbuild emits the GraphiQL server into a top-level shared chunk or a nested command file. build.onLoad({filter: /[/\\]graphiql[/\\]server\.[cm]?[jt]s$/}, async (args) => { const contents = await readFile(args.path, 'utf8') + if (!createRequireStatement.test(contents)) { + throw new Error(`Could not find the GraphiQL server createRequire statement in ${args.path}`) + } // When `contents` is returned, esbuild defaults the loader to `js` unless set — TypeScript would then // fail to parse (e.g. "Expected ')' but found ':'" on parameter type annotations). const loader = args.path.endsWith('.tsx') ? 'tsx' : 'ts' return { loader, contents: contents - .replace('@shopify/app/assets/graphiql/favicon.ico', '../../../assets/graphiql/favicon.ico') - .replace('@shopify/app/assets/graphiql/style.css', '../../../assets/graphiql/style.css'), + .replace(createRequireStatement, (match) => `${match}\n${resolveGraphiQLAssetHelper}`) + .replace("require.resolve('@shopify/cli-kit/assets/graphiql/favicon.ico')", "resolveGraphiQLAsset('favicon.ico')") + .replace("require.resolve('@shopify/cli-kit/assets/graphiql/style.css')", "resolveGraphiQLAsset('style.css')"), } }) }, diff --git a/docs-shopify.dev/commands/config-autoupgrade-off.doc.ts b/docs-shopify.dev/commands/config-autoupgrade-off.doc.ts deleted file mode 100644 index 75b62ff3224..00000000000 --- a/docs-shopify.dev/commands/config-autoupgrade-off.doc.ts +++ /dev/null @@ -1,34 +0,0 @@ -// This is an autogenerated file. Don't edit this file manually. -import {ReferenceEntityTemplateSchema} from '@shopify/generate-docs' - -const data: ReferenceEntityTemplateSchema = { - name: 'config autoupgrade off', - description: `Disable automatic upgrades for Shopify CLI. - - When auto-upgrade is disabled, Shopify CLI won't automatically update. Run \`shopify upgrade\` to update manually. - - To enable auto-upgrade, run \`shopify config autoupgrade on\`. -`, - overviewPreviewDescription: `Disable automatic upgrades for Shopify CLI.`, - type: 'command', - isVisualComponent: false, - defaultExample: { - codeblock: { - tabs: [ - { - title: 'config autoupgrade off', - code: './examples/config-autoupgrade-off.example.sh', - language: 'bash', - }, - ], - title: 'config autoupgrade off', - }, - }, - definitions: [ - ], - category: 'general commands', - related: [ - ], -} - -export default data \ No newline at end of file diff --git a/docs-shopify.dev/commands/config-autoupgrade-on.doc.ts b/docs-shopify.dev/commands/config-autoupgrade-on.doc.ts deleted file mode 100644 index acc5bb39026..00000000000 --- a/docs-shopify.dev/commands/config-autoupgrade-on.doc.ts +++ /dev/null @@ -1,34 +0,0 @@ -// This is an autogenerated file. Don't edit this file manually. -import {ReferenceEntityTemplateSchema} from '@shopify/generate-docs' - -const data: ReferenceEntityTemplateSchema = { - name: 'config autoupgrade on', - description: `Enable automatic upgrades for Shopify CLI. - - When auto-upgrade is enabled, Shopify CLI automatically updates to the latest version once per day. Major version upgrades are skipped and must be done manually. - - To disable auto-upgrade, run \`shopify config autoupgrade off\`. -`, - overviewPreviewDescription: `Enable automatic upgrades for Shopify CLI.`, - type: 'command', - isVisualComponent: false, - defaultExample: { - codeblock: { - tabs: [ - { - title: 'config autoupgrade on', - code: './examples/config-autoupgrade-on.example.sh', - language: 'bash', - }, - ], - title: 'config autoupgrade on', - }, - }, - definitions: [ - ], - category: 'general commands', - related: [ - ], -} - -export default data \ No newline at end of file diff --git a/docs-shopify.dev/commands/config-autoupgrade-status.doc.ts b/docs-shopify.dev/commands/config-autoupgrade-status.doc.ts deleted file mode 100644 index fce1d30aac7..00000000000 --- a/docs-shopify.dev/commands/config-autoupgrade-status.doc.ts +++ /dev/null @@ -1,34 +0,0 @@ -// This is an autogenerated file. Don't edit this file manually. -import {ReferenceEntityTemplateSchema} from '@shopify/generate-docs' - -const data: ReferenceEntityTemplateSchema = { - name: 'config autoupgrade status', - description: `Check whether auto-upgrade is enabled, disabled, or not yet configured. - - When auto-upgrade is enabled, Shopify CLI automatically updates to the latest version after each command. - - Run \`shopify config autoupgrade on\` or \`shopify config autoupgrade off\` to configure it. -`, - overviewPreviewDescription: `Check whether auto-upgrade is enabled, disabled, or not yet configured.`, - type: 'command', - isVisualComponent: false, - defaultExample: { - codeblock: { - tabs: [ - { - title: 'config autoupgrade status', - code: './examples/config-autoupgrade-status.example.sh', - language: 'bash', - }, - ], - title: 'config autoupgrade status', - }, - }, - definitions: [ - ], - category: 'general commands', - related: [ - ], -} - -export default data \ No newline at end of file diff --git a/docs-shopify.dev/commands/examples/config-autoupgrade-off.example.sh b/docs-shopify.dev/commands/examples/config-autoupgrade-off.example.sh deleted file mode 100644 index e6b28d09bd1..00000000000 --- a/docs-shopify.dev/commands/examples/config-autoupgrade-off.example.sh +++ /dev/null @@ -1 +0,0 @@ -shopify config autoupgrade off \ No newline at end of file diff --git a/docs-shopify.dev/commands/examples/config-autoupgrade-on.example.sh b/docs-shopify.dev/commands/examples/config-autoupgrade-on.example.sh deleted file mode 100644 index 71f0109cbb5..00000000000 --- a/docs-shopify.dev/commands/examples/config-autoupgrade-on.example.sh +++ /dev/null @@ -1 +0,0 @@ -shopify config autoupgrade on \ No newline at end of file diff --git a/docs-shopify.dev/commands/examples/config-autoupgrade-status.example.sh b/docs-shopify.dev/commands/examples/config-autoupgrade-status.example.sh deleted file mode 100644 index 5c94f013999..00000000000 --- a/docs-shopify.dev/commands/examples/config-autoupgrade-status.example.sh +++ /dev/null @@ -1 +0,0 @@ -shopify config autoupgrade status \ No newline at end of file diff --git a/packages/app/package.json b/packages/app/package.json index c2d7fec0cc9..486e0ee5db3 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -64,8 +64,6 @@ "@shopify/cli-kit": "4.1.0", "@shopify/plugin-cloudflare": "4.1.0", "@shopify/organizations": "4.1.0", - "@shopify/polaris": "12.27.0", - "@shopify/polaris-icons": "8.11.1", "@shopify/theme": "4.1.0", "@shopify/theme-check-node": "3.26.1", "@shopify/toml-patch": "0.3.0", @@ -80,7 +78,6 @@ "prettier": "3.8.4", "proper-lockfile": "4.1.2", "react": "19.2.4", - "react-dom": "19.2.4", "which": "4.0.0", "ws": "8.21.0" }, @@ -88,7 +85,6 @@ "@types/diff": "^5.0.3", "@types/proper-lockfile": "4.1.4", "@types/react": "^19.0.0", - "@types/react-dom": "^19.0.0", "@types/which": "3.0.4", "@types/ws": "^8.5.13", "@vitest/coverage-istanbul": "^3.1.4" diff --git a/packages/app/src/cli/services/dev/processes/graphiql.ts b/packages/app/src/cli/services/dev/processes/graphiql.ts index 6b00d808c55..06776b27e78 100644 --- a/packages/app/src/cli/services/dev/processes/graphiql.ts +++ b/packages/app/src/cli/services/dev/processes/graphiql.ts @@ -1,5 +1,5 @@ import {BaseProcess, DevProcessFunction} from './types.js' -import {setupGraphiQLServer} from '../graphiql/server.js' +import {setupGraphiQLServer} from '@shopify/cli-kit/node/graphiql/server' interface GraphiQLServerProcessOptions { appName: string diff --git a/packages/app/src/cli/services/dev/processes/setup-dev-processes.test.ts b/packages/app/src/cli/services/dev/processes/setup-dev-processes.test.ts index aeb6702a4ea..06ad0ad0f00 100644 --- a/packages/app/src/cli/services/dev/processes/setup-dev-processes.test.ts +++ b/packages/app/src/cli/services/dev/processes/setup-dev-processes.test.ts @@ -8,7 +8,6 @@ import {pushUpdatesForDraftableExtensions} from './draftable-extension.js' import {pushUpdatesForDevSession} from './dev-session/dev-session-process.js' import {runThemeAppExtensionsServer} from './theme-app-extension.js' import {launchAppWatcher} from './app-watcher-process.js' -import {resolveGraphiQLKey} from '../graphiql/server.js' import { testAppAccessConfigExtension, testAppConfigExtensions, @@ -31,6 +30,7 @@ import {ensureDeploymentIdsPresence} from '../../context/identifiers.js' import {DeveloperPlatformClient} from '../../../utilities/developer-platform-client.js' import {AppEventWatcher} from '../app-events/app-event-watcher.js' import * as loader from '../../../models/app/loader.js' +import {resolveGraphiQLKey} from '@shopify/cli-kit/node/graphiql/server' import {describe, test, expect, beforeEach, vi} from 'vitest' import {ensureAuthenticatedAdmin, ensureAuthenticatedStorefront} from '@shopify/cli-kit/node/session' import {Config} from '@oclif/core' diff --git a/packages/app/src/cli/services/dev/processes/setup-dev-processes.ts b/packages/app/src/cli/services/dev/processes/setup-dev-processes.ts index 0c6ca0b2f6d..9feb2b29f07 100644 --- a/packages/app/src/cli/services/dev/processes/setup-dev-processes.ts +++ b/packages/app/src/cli/services/dev/processes/setup-dev-processes.ts @@ -9,7 +9,6 @@ import {DevSessionProcess, setupDevSessionProcess} from './dev-session/dev-sessi import {AppLogsSubscribeProcess, setupAppLogsPollingProcess} from './app-logs-polling.js' import {AppWatcherProcess, setupAppWatcherProcess} from './app-watcher-process.js' import {DevSessionStatusManager} from './dev-session/dev-session-status-manager.js' -import {resolveGraphiQLKey} from '../graphiql/server.js' import {environmentVariableNames} from '../../../constants.js' import {AppLinkedInterface, getAppScopes, WebType} from '../../../models/app/app.js' @@ -21,6 +20,7 @@ import {ApplicationURLs} from '../urls.js' import {DeveloperPlatformClient} from '../../../utilities/developer-platform-client.js' import {AppEventWatcher} from '../app-events/app-event-watcher.js' import {reloadApp} from '../../../models/app/loader.js' +import {resolveGraphiQLKey} from '@shopify/cli-kit/node/graphiql/server' import {getAvailableTCPPort} from '@shopify/cli-kit/node/tcp' import {isTruthy} from '@shopify/cli-kit/node/context/utilities' import {firstPartyDev} from '@shopify/cli-kit/node/context/local' diff --git a/packages/app/assets/graphiql/favicon.ico b/packages/cli-kit/assets/graphiql/favicon.ico similarity index 100% rename from packages/app/assets/graphiql/favicon.ico rename to packages/cli-kit/assets/graphiql/favicon.ico diff --git a/packages/app/assets/graphiql/style.css b/packages/cli-kit/assets/graphiql/style.css similarity index 100% rename from packages/app/assets/graphiql/style.css rename to packages/cli-kit/assets/graphiql/style.css diff --git a/packages/cli-kit/package.json b/packages/cli-kit/package.json index 2f6720eab3d..c5fac1272f1 100644 --- a/packages/cli-kit/package.json +++ b/packages/cli-kit/package.json @@ -107,6 +107,8 @@ "@graphql-typed-document-node/core": "3.2.0", "@iarna/toml": "2.2.5", "@oclif/core": "4.11.4", + "@shopify/polaris": "12.27.0", + "@shopify/polaris-icons": "8.11.1", "@shopify/toml-patch": "0.3.0", "@opentelemetry/api": "1.9.1", "@opentelemetry/core": "1.30.1", @@ -134,6 +136,7 @@ "gradient-string": "2.0.2", "graphql": "16.14.2", "graphql-request": "6.1.0", + "h3": "1.15.11", "ignore": "6.0.2", "ink": "6.8.0", "is-executable": "2.0.2", @@ -152,6 +155,7 @@ "pathe": "1.1.2", "react": "19.2.4", "semver": "7.8.4", + "react-dom": "19.2.4", "stacktracey": "2.2.0", "strip-ansi": "7.2.0", "supports-hyperlinks": "3.2.0", @@ -165,6 +169,7 @@ "@types/gradient-string": "^1.1.2", "@types/lodash": "4.17.24", "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", "@types/semver": "^7.5.2", "@types/which": "3.0.4", "@vitest/coverage-istanbul": "^3.1.4", diff --git a/packages/app/src/cli/services/dev/graphiql/server.test.ts b/packages/cli-kit/src/public/node/graphiql/server.test.ts similarity index 100% rename from packages/app/src/cli/services/dev/graphiql/server.test.ts rename to packages/cli-kit/src/public/node/graphiql/server.test.ts diff --git a/packages/app/src/cli/services/dev/graphiql/server.ts b/packages/cli-kit/src/public/node/graphiql/server.ts similarity index 82% rename from packages/app/src/cli/services/dev/graphiql/server.ts rename to packages/cli-kit/src/public/node/graphiql/server.ts index 4ee8646d38a..4b83473910d 100644 --- a/packages/app/src/cli/services/dev/graphiql/server.ts +++ b/packages/cli-kit/src/public/node/graphiql/server.ts @@ -1,6 +1,13 @@ import {defaultQuery, graphiqlTemplate} from './templates/graphiql.js' import {unauthorizedTemplate} from './templates/unauthorized.js' import {filterCustomHeaders} from './utilities.js' +import {performActionWithRetryAfterRecovery} from '../../common/retry.js' +import {CLI_KIT_VERSION} from '../../common/version.js' +import {AbortError} from '../error.js' +import {adminUrl, supportedApiVersions} from '../api/admin.js' +import {fetch} from '../http.js' +import {renderLiquidTemplate} from '../liquid.js' +import {outputDebug} from '../output.js' import { createApp, createRouter, @@ -13,13 +20,6 @@ import { setResponseStatus, toNodeListener, } from 'h3' -import {performActionWithRetryAfterRecovery} from '@shopify/cli-kit/common/retry' -import {CLI_KIT_VERSION} from '@shopify/cli-kit/common/version' -import {AbortError} from '@shopify/cli-kit/node/error' -import {adminUrl, supportedApiVersions} from '@shopify/cli-kit/node/api/admin' -import {fetch} from '@shopify/cli-kit/node/http' -import {renderLiquidTemplate} from '@shopify/cli-kit/node/liquid' -import {outputDebug} from '@shopify/cli-kit/node/output' import {createHmac} from 'crypto' import {createServer, Server} from 'http' import {readFileSync} from 'fs' @@ -30,6 +30,10 @@ import {createRequire} from 'module' * Derives a deterministic GraphiQL authentication key from the app's API secret and store FQDN. * The key is stable across dev server restarts (so browser tabs survive restarts) * but is not guessable without the app secret. + * + * @param apiSecret - The Partners app's client secret used as the HMAC key. + * @param storeFqdn - The myshopify.com domain the GraphiQL session targets. + * @returns A 64-character hex string suitable for use as the `?key=` query param. */ export function deriveGraphiQLKey(apiSecret: string, storeFqdn: string): string { return createHmac('sha256', apiSecret).update(`graphiql:${storeFqdn}`).digest('hex') @@ -38,6 +42,11 @@ export function deriveGraphiQLKey(apiSecret: string, storeFqdn: string): string /** * Resolves the GraphiQL authentication key. Uses the explicitly provided key * if non-empty, otherwise derives one deterministically from the app secret. + * + * @param providedKey - An explicit key supplied by the caller; takes precedence when non-empty. + * @param apiSecret - The Partners app's client secret, used to derive a stable key as a fallback. + * @param storeFqdn - The myshopify.com domain the GraphiQL session targets. + * @returns The resolved key. */ export function resolveGraphiQLKey(providedKey: string | undefined, apiSecret: string, storeFqdn: string): string { // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional: empty string after trim should fall through to deriveGraphiQLKey @@ -63,16 +72,18 @@ interface SetupGraphiQLServerOptions { storeFqdn: string } -export function setupGraphiQLServer({ - stdout, - port, - appName, - appUrl, - apiKey, - apiSecret, - key: providedKey, - storeFqdn, -}: SetupGraphiQLServerOptions): Server { +/** + * Starts a local HTTP server that hosts the GraphiQL UI and proxies requests to the + * Admin API for the configured store. The server uses the OAuth `client_credentials` + * grant with the supplied `apiKey` / `apiSecret` to mint and refresh access tokens + * on the fly. + * + * @param options - Configuration for the server, including the target store, the + * Partners app credentials, and the local port to bind to. + * @returns The underlying Node `http.Server` instance, already listening on `options.port`. + */ +export function setupGraphiQLServer(options: SetupGraphiQLServerOptions): Server { + const {stdout, port, appName, appUrl, apiKey, apiSecret, key: providedKey, storeFqdn} = options // Always require an authentication key. If not explicitly provided, derive one // deterministically from apiSecret + storeFqdn so the key is stable across restarts // (browser tabs survive dev server restarts) but not guessable without the app secret. @@ -120,9 +131,9 @@ export function setupGraphiQLServer({ ) } - const faviconPath = require.resolve('@shopify/app/assets/graphiql/favicon.ico') + const faviconPath = require.resolve('@shopify/cli-kit/assets/graphiql/favicon.ico') const faviconContent = readFileSync(faviconPath) - const stylePath = require.resolve('@shopify/app/assets/graphiql/style.css') + const stylePath = require.resolve('@shopify/cli-kit/assets/graphiql/style.css') const styleContent = readFileSync(stylePath, 'utf8') app.use( diff --git a/packages/app/src/cli/services/dev/graphiql/templates/graphiql.tsx b/packages/cli-kit/src/public/node/graphiql/templates/graphiql.tsx similarity index 99% rename from packages/app/src/cli/services/dev/graphiql/templates/graphiql.tsx rename to packages/cli-kit/src/public/node/graphiql/templates/graphiql.tsx index a14e1e0c9d6..edc3638df34 100644 --- a/packages/app/src/cli/services/dev/graphiql/templates/graphiql.tsx +++ b/packages/cli-kit/src/public/node/graphiql/templates/graphiql.tsx @@ -1,4 +1,4 @@ -import {platformAndArch} from '@shopify/cli-kit/node/os' +import {platformAndArch} from '../../os.js' import React from 'react' import {renderToStaticMarkup} from 'react-dom/server' import {AppProvider, Badge, Banner, BlockStack, Box, Grid, InlineStack, Link, Select, Text} from '@shopify/polaris' diff --git a/packages/app/src/cli/services/dev/graphiql/templates/unauthorized.tsx b/packages/cli-kit/src/public/node/graphiql/templates/unauthorized.tsx similarity index 100% rename from packages/app/src/cli/services/dev/graphiql/templates/unauthorized.tsx rename to packages/cli-kit/src/public/node/graphiql/templates/unauthorized.tsx diff --git a/packages/app/src/cli/services/dev/graphiql/utilities.test.ts b/packages/cli-kit/src/public/node/graphiql/utilities.test.ts similarity index 100% rename from packages/app/src/cli/services/dev/graphiql/utilities.test.ts rename to packages/cli-kit/src/public/node/graphiql/utilities.test.ts diff --git a/packages/app/src/cli/services/dev/graphiql/utilities.ts b/packages/cli-kit/src/public/node/graphiql/utilities.ts similarity index 80% rename from packages/app/src/cli/services/dev/graphiql/utilities.ts rename to packages/cli-kit/src/public/node/graphiql/utilities.ts index d900e443093..85573897f08 100644 --- a/packages/app/src/cli/services/dev/graphiql/utilities.ts +++ b/packages/cli-kit/src/public/node/graphiql/utilities.ts @@ -1,9 +1,9 @@ /** * Headers that should NOT be forwarded from the GraphiQL client to the Admin API. * These include: - * - Hop-by-hop headers (RFC 7230) that are connection-specific - * - Browser-specific headers that are not relevant to API requests - * - Headers the proxy sets itself (auth, content-type, etc.) + * - Hop-by-hop headers (RFC 7230) that are connection-specific. + * - Browser-specific headers that are not relevant to API requests. + * - Headers the proxy sets itself (auth, content-type, etc.). */ const BLOCKED_HEADERS = new Set([ // Hop-by-hop headers (RFC 7230 Section 6.1) @@ -30,6 +30,9 @@ const BLOCKED_HEADERS = new Set([ /** * Filters request headers to extract only custom headers that are safe to forward. * Blocked headers and non-string values are excluded. + * + * @param headers - The raw incoming request headers. + * @returns The subset of headers that are safe to forward to the Admin API. */ export function filterCustomHeaders(headers: {[key: string]: string | string[] | undefined}): {[key: string]: string} { const customHeaders: {[key: string]: string} = {} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b11d7cfa4b7..d45dc68ce1b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -163,12 +163,6 @@ importers: '@shopify/plugin-cloudflare': specifier: 4.1.0 version: link:../plugin-cloudflare - '@shopify/polaris': - specifier: 12.27.0 - version: 12.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@shopify/polaris-icons': - specifier: 8.11.1 - version: 8.11.1(react@19.2.4) '@shopify/theme': specifier: 4.1.0 version: link:../theme @@ -211,9 +205,6 @@ importers: react: specifier: 19.2.4 version: 19.2.4 - react-dom: - specifier: 19.2.4 - version: 19.2.4(react@19.2.4) which: specifier: 4.0.0 version: 4.0.0 @@ -230,9 +221,6 @@ importers: '@types/react': specifier: 18.3.12 version: 18.3.12 - '@types/react-dom': - specifier: ^19.0.0 - version: 19.2.3(@types/react@18.3.12) '@types/which': specifier: 3.0.4 version: 3.0.4 @@ -327,6 +315,12 @@ importers: '@opentelemetry/sdk-metrics': specifier: 1.30.1 version: 1.30.1(@opentelemetry/api@1.9.1) + '@shopify/polaris': + specifier: 12.27.0 + version: 12.27.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@shopify/polaris-icons': + specifier: 8.11.1 + version: 8.11.1(react@19.2.4) '@shopify/toml-patch': specifier: 0.3.0 version: 0.3.0 @@ -393,6 +387,9 @@ importers: graphql-request: specifier: 6.1.0 version: 6.1.0(graphql@16.14.2) + h3: + specifier: 1.15.11 + version: 1.15.11 ignore: specifier: 6.0.2 version: 6.0.2 @@ -444,6 +441,9 @@ importers: react: specifier: 19.2.4 version: 19.2.4 + react-dom: + specifier: 19.2.4 + version: 19.2.4(react@19.2.4) semver: specifier: 7.8.4 version: 7.8.4 @@ -481,6 +481,9 @@ importers: '@types/react': specifier: 18.3.12 version: 18.3.12 + '@types/react-dom': + specifier: ^19.0.0 + version: 19.2.3(@types/react@18.3.12) '@types/semver': specifier: ^7.5.2 version: 7.7.1