From 20bc495ff07ed1bb2dbb4d77e349e09750cbec89 Mon Sep 17 00:00:00 2001 From: Gonzalo Riestra Date: Thu, 11 Dec 2025 16:34:34 +0000 Subject: [PATCH] Merge pull request #6708 from Shopify/unblock-partners-api Unblock Partners API --- .changeset/clear-humans-sip.md | 6 +++++ .../app/src/cli/services/dev/fetch.test.ts | 5 ++++ .../utilities/developer-platform-client.ts | 5 ++-- .../cli-kit/src/private/node/constants.ts | 1 - .../src/public/node/api/partners.test.ts | 26 +++++++++++++++++++ .../cli-kit/src/public/node/api/partners.ts | 7 ++++- .../src/public/node/context/fqdn.test.ts | 14 ++++------ .../cli-kit/src/public/node/context/fqdn.ts | 6 +---- .../cli-kit/src/public/node/environment.ts | 13 +--------- 9 files changed, 53 insertions(+), 30 deletions(-) create mode 100644 .changeset/clear-humans-sip.md diff --git a/.changeset/clear-humans-sip.md b/.changeset/clear-humans-sip.md new file mode 100644 index 00000000000..efad7c184e5 --- /dev/null +++ b/.changeset/clear-humans-sip.md @@ -0,0 +1,6 @@ +--- +'@shopify/cli-kit': patch +'@shopify/app': patch +--- + +Unblock Partners API to fix import-extensions diff --git a/packages/app/src/cli/services/dev/fetch.test.ts b/packages/app/src/cli/services/dev/fetch.test.ts index 73e9c40cef3..633ec6fb5f5 100644 --- a/packages/app/src/cli/services/dev/fetch.test.ts +++ b/packages/app/src/cli/services/dev/fetch.test.ts @@ -12,6 +12,7 @@ import {afterEach, describe, expect, test, vi} from 'vitest' import {renderFatalError} from '@shopify/cli-kit/node/ui' import {mockAndCaptureOutput} from '@shopify/cli-kit/node/testing/output' import {AbortError} from '@shopify/cli-kit/node/error' +import {blockPartnersAccess} from '@shopify/cli-kit/node/environment' const ORG1: Organization = { id: '1', @@ -36,6 +37,7 @@ const STORE1: OrganizationStore = { vi.mock('@shopify/cli-kit/node/api/partners') vi.mock('../../utilities/developer-platform-client/partners-client.js') vi.mock('../../utilities/developer-platform-client/app-management-client.js') +vi.mock('@shopify/cli-kit/node/environment') afterEach(() => { mockAndCaptureOutput().clear() @@ -46,6 +48,7 @@ describe('fetchOrganizations', async () => { test('returns fetched organizations from Partners and App Management for 1P development', async () => { // Given vi.stubEnv('SHOPIFY_CLI_1P_DEV', 'true') + vi.mocked(blockPartnersAccess).mockReturnValue(false) const partnersClient: PartnersClient = testDeveloperPlatformClient({ organizations: () => Promise.resolve([ORG1]), }) as PartnersClient @@ -66,6 +69,7 @@ describe('fetchOrganizations', async () => { test('returns fetched organizations from App Management for 3P development', async () => { // Given + vi.mocked(blockPartnersAccess).mockReturnValue(true) const appManagementClient: AppManagementClient = testDeveloperPlatformClient({ organizations: () => Promise.resolve([ORG2]), }) as AppManagementClient @@ -82,6 +86,7 @@ describe('fetchOrganizations', async () => { test('throws if there are no organizations', async () => { // Given + vi.mocked(blockPartnersAccess).mockReturnValue(true) const appManagementClient: AppManagementClient = testDeveloperPlatformClient({ organizations: () => Promise.resolve([]), }) as AppManagementClient diff --git a/packages/app/src/cli/utilities/developer-platform-client.ts b/packages/app/src/cli/utilities/developer-platform-client.ts index a919f8e00e6..d3b16261ea2 100644 --- a/packages/app/src/cli/utilities/developer-platform-client.ts +++ b/packages/app/src/cli/utilities/developer-platform-client.ts @@ -61,6 +61,7 @@ import {TokenItem} from '@shopify/cli-kit/node/ui' import {blockPartnersAccess} from '@shopify/cli-kit/node/environment' import {UnauthorizedHandler} from '@shopify/cli-kit/node/api/graphql' import {JsonMapType} from '@shopify/cli-kit/node/toml' +import {firstPartyDev} from '@shopify/cli-kit/node/context/local' export enum ClientName { AppManagement = 'app-management', @@ -105,9 +106,9 @@ function selectDeveloperPlatformClientByOrg(organization: Organization): Develop } function defaultDeveloperPlatformClient(): DeveloperPlatformClient { - if (blockPartnersAccess()) return AppManagementClient.getInstance() + if (firstPartyDev() && !blockPartnersAccess()) return PartnersClient.getInstance() - return PartnersClient.getInstance() + return AppManagementClient.getInstance() } export interface CreateAppOptions { diff --git a/packages/cli-kit/src/private/node/constants.ts b/packages/cli-kit/src/private/node/constants.ts index 732ace3106d..d76fba74700 100644 --- a/packages/cli-kit/src/private/node/constants.ts +++ b/packages/cli-kit/src/private/node/constants.ts @@ -43,7 +43,6 @@ export const environmentVariables = { themeKitAccessDomain: 'SHOPIFY_CLI_THEME_KIT_ACCESS_DOMAIN', json: 'SHOPIFY_FLAG_JSON', neverUsePartnersApi: 'SHOPIFY_CLI_NEVER_USE_PARTNERS_API', - usePartnersApi: 'SHOPIFY_CLI_USE_PARTNERS_API', skipNetworkLevelRetry: 'SHOPIFY_CLI_SKIP_NETWORK_LEVEL_RETRY', maxRequestTimeForNetworkCalls: 'SHOPIFY_CLI_MAX_REQUEST_TIME_FOR_NETWORK_CALLS', } diff --git a/packages/cli-kit/src/public/node/api/partners.test.ts b/packages/cli-kit/src/public/node/api/partners.test.ts index e3597f2b6db..d287b4d4539 100644 --- a/packages/cli-kit/src/public/node/api/partners.test.ts +++ b/packages/cli-kit/src/public/node/api/partners.test.ts @@ -1,12 +1,15 @@ import {partnersRequest, handleDeprecations} from './partners.js' import {graphqlRequest, GraphQLResponse} from './graphql.js' import {partnersFqdn} from '../context/fqdn.js' +import {blockPartnersAccess} from '../environment.js' +import {BugError} from '../error.js' import {setNextDeprecationDate} from '../../../private/node/context/deprecations-store.js' import {test, vi, expect, describe, beforeEach, beforeAll} from 'vitest' vi.mock('./graphql.js') vi.mock('../../../private/node/context/deprecations-store.js') vi.mock('../context/fqdn.js') +vi.mock('../environment.js') const mockedResult = 'OK' const partnersFQDN = 'partners.shopify.com' @@ -16,6 +19,7 @@ const mockedToken = 'token' beforeEach(() => { vi.mocked(partnersFqdn).mockResolvedValue(partnersFQDN) + vi.mocked(blockPartnersAccess).mockReturnValue(false) }) describe('partnersRequest', () => { @@ -36,6 +40,28 @@ describe('partnersRequest', () => { responseOptions: {onResponse: handleDeprecations}, }) }) + + test('throws BugError when blockPartnersAccess returns true', async () => { + // Given + vi.mocked(blockPartnersAccess).mockReturnValue(true) + + // When/Then + await expect(partnersRequest('query', mockedToken, {variables: 'variables'})).rejects.toThrow(BugError) + expect(blockPartnersAccess).toHaveBeenCalled() + }) + + test('does not throw when blockPartnersAccess returns false', async () => { + // Given + vi.mocked(blockPartnersAccess).mockReturnValue(false) + vi.mocked(graphqlRequest).mockResolvedValue(mockedResult) + + // When + await partnersRequest('query', mockedToken, {variables: 'variables'}) + + // Then + expect(blockPartnersAccess).toHaveBeenCalled() + expect(graphqlRequest).toHaveBeenCalled() + }) }) describe('handleDeprecations', () => { diff --git a/packages/cli-kit/src/public/node/api/partners.ts b/packages/cli-kit/src/public/node/api/partners.ts index 8da3c7ac11b..82903a392cf 100644 --- a/packages/cli-kit/src/public/node/api/partners.ts +++ b/packages/cli-kit/src/public/node/api/partners.ts @@ -11,9 +11,10 @@ import {partnersFqdn} from '../context/fqdn.js' import {setNextDeprecationDate} from '../../../private/node/context/deprecations-store.js' import {getPackageManager} from '../node-package-manager.js' import {cwd} from '../path.js' -import {AbortError} from '../error.js' +import {AbortError, BugError} from '../error.js' import {formatPackageManagerCommand} from '../output.js' import {RequestModeInput} from '../http.js' +import {blockPartnersAccess} from '../environment.js' import Bottleneck from 'bottleneck' import {Variables} from 'graphql-request' import {TypedDocumentNode} from '@graphql-typed-document-node/core' @@ -32,6 +33,10 @@ const limiter = new Bottleneck({ * @param token - Partners token. */ async function setupRequest(token: string) { + if (blockPartnersAccess()) { + throw new BugError('Partners API is no longer available.') + } + const api = 'Partners' const fqdn = await partnersFqdn() const url = `https://${fqdn}/api/cli/graphql` diff --git a/packages/cli-kit/src/public/node/context/fqdn.test.ts b/packages/cli-kit/src/public/node/context/fqdn.test.ts index c867540fc31..72f51b35dda 100644 --- a/packages/cli-kit/src/public/node/context/fqdn.test.ts +++ b/packages/cli-kit/src/public/node/context/fqdn.test.ts @@ -8,11 +8,9 @@ import { adminFqdn, } from './fqdn.js' import {Environment, serviceEnvironment} from '../../../private/node/context/service.js' -import {blockPartnersAccess} from '../environment.js' import {expect, describe, test, vi} from 'vitest' vi.mock('../../../private/node/context/service.js') -vi.mock('../environment.js') vi.mock('../vendor/dev_server/index.js', () => { return { @@ -34,7 +32,6 @@ describe('partners', () => { test('returns the local fqdn when the environment is local', async () => { // Given vi.mocked(serviceEnvironment).mockReturnValue(Environment.Local) - vi.mocked(blockPartnersAccess).mockReturnValue(false) // When const got = await partnersFqdn() @@ -46,7 +43,6 @@ describe('partners', () => { test('returns the production fqdn when the environment is production', async () => { // Given vi.mocked(serviceEnvironment).mockReturnValue(Environment.Production) - vi.mocked(blockPartnersAccess).mockReturnValue(false) // When const got = await partnersFqdn() @@ -181,7 +177,7 @@ describe('adminFqdn', () => { describe('normalizeStore', () => { test('parses store name with http', async () => { // When - const got = await normalizeStoreFqdn('http://example.myshopify.com') + const got = normalizeStoreFqdn('http://example.myshopify.com') // Then expect(got).toEqual('example.myshopify.com') @@ -189,7 +185,7 @@ describe('normalizeStore', () => { test('parses store name with https', async () => { // When - const got = await normalizeStoreFqdn('https://example.myshopify.com') + const got = normalizeStoreFqdn('https://example.myshopify.com') // Then expect(got).toEqual('example.myshopify.com') @@ -197,7 +193,7 @@ describe('normalizeStore', () => { test('parses store name without domain', async () => { // When - const got = await normalizeStoreFqdn('example') + const got = normalizeStoreFqdn('example') // Then expect(got).toEqual('example.myshopify.com') @@ -208,7 +204,7 @@ describe('normalizeStore', () => { vi.mocked(serviceEnvironment).mockReturnValue(Environment.Local) // When - const got = await normalizeStoreFqdn('example') + const got = normalizeStoreFqdn('example') // Then expect(got).toEqual('example.myshopify.io') @@ -216,7 +212,7 @@ describe('normalizeStore', () => { test('parses store name with admin', async () => { // When - const got = await normalizeStoreFqdn('https://example.myshopify.com/admin/') + const got = normalizeStoreFqdn('https://example.myshopify.com/admin/') // Then expect(got).toEqual('example.myshopify.com') diff --git a/packages/cli-kit/src/public/node/context/fqdn.ts b/packages/cli-kit/src/public/node/context/fqdn.ts index c45d1999c64..a41be33e161 100644 --- a/packages/cli-kit/src/public/node/context/fqdn.ts +++ b/packages/cli-kit/src/public/node/context/fqdn.ts @@ -1,7 +1,6 @@ -import {AbortError, BugError} from '../error.js' +import {AbortError} from '../error.js' import {serviceEnvironment} from '../../../private/node/context/service.js' import {DevServer, DevServerCore} from '../vendor/dev_server/index.js' -import {blockPartnersAccess} from '../environment.js' export const NotProvidedStoreFQDNError = new AbortError( "Couldn't obtain the Shopify FQDN because the store FQDN was not provided.", @@ -13,9 +12,6 @@ export const NotProvidedStoreFQDNError = new AbortError( * @returns Fully-qualified domain of the partners service we should interact with. */ export async function partnersFqdn(): Promise { - if (blockPartnersAccess()) { - throw new BugError('Partners API is is no longer available.') - } const environment = serviceEnvironment() const productionFqdn = 'partners.shopify.com' switch (environment) { diff --git a/packages/cli-kit/src/public/node/environment.ts b/packages/cli-kit/src/public/node/environment.ts index ad1ce55c7e0..653b4895d75 100644 --- a/packages/cli-kit/src/public/node/environment.ts +++ b/packages/cli-kit/src/public/node/environment.ts @@ -89,18 +89,7 @@ export function jsonOutputEnabled(environment = getEnvironmentVariables()): bool * @returns True when the CLI should not use the Partners API. */ export function blockPartnersAccess(): boolean { - // Block if explicitly set to never use Partners API - if (isTruthy(getEnvironmentVariables()[environmentVariables.neverUsePartnersApi])) { - return true - } - - // If explicitly forcing to use Partners API, do not block - if (isTruthy(getEnvironmentVariables()[environmentVariables.usePartnersApi])) { - return false - } - - // Block for 3P devs - return !isTruthy(getEnvironmentVariables()[environmentVariables.firstPartyDev]) + return isTruthy(getEnvironmentVariables()[environmentVariables.neverUsePartnersApi]) } /**