From 589cb8d1e72a5ff24a2670f8674ac562a70247b1 Mon Sep 17 00:00:00 2001 From: Gonzalo Riestra Date: Thu, 20 Nov 2025 17:42:12 +0100 Subject: [PATCH] Block Partners API for 3P devs --- .../app-logs/dev/poll-app-logs.test.ts | 5 ++-- .../app/src/cli/services/dev/fetch.test.ts | 24 ++++++++++++++----- .../utilities/developer-platform-client.ts | 8 ++++++- .../src/public/node/context/fqdn.test.ts | 4 ++++ .../cli-kit/src/public/node/context/fqdn.ts | 2 +- .../cli-kit/src/public/node/environment.ts | 7 ++++-- 6 files changed, 37 insertions(+), 13 deletions(-) diff --git a/packages/app/src/cli/services/app-logs/dev/poll-app-logs.test.ts b/packages/app/src/cli/services/app-logs/dev/poll-app-logs.test.ts index 83fbd22f721..38a5022fd0b 100644 --- a/packages/app/src/cli/services/app-logs/dev/poll-app-logs.test.ts +++ b/packages/app/src/cli/services/app-logs/dev/poll-app-logs.test.ts @@ -2,20 +2,19 @@ import {pollAppLogs} from './poll-app-logs.js' import {writeAppLogsToFile} from './write-app-logs.js' import {FunctionRunLog} from '../types.js' import {testDeveloperPlatformClient} from '../../../models/app/app.test-data.js' -import {partnersFqdn} from '@shopify/cli-kit/node/context/fqdn' import {describe, expect, test, vi, beforeEach, afterEach} from 'vitest' import * as components from '@shopify/cli-kit/node/ui/components' import * as output from '@shopify/cli-kit/node/output' import camelcaseKeys from 'camelcase-keys' +import {appManagementFqdn} from '@shopify/cli-kit/node/context/fqdn' const JWT_TOKEN = 'jwtToken' -const API_KEY = 'apiKey' const TEST_LOGS_DIR = '/test/logs/dir' vi.mock('./write-app-logs.js') vi.mock('@shopify/cli-kit/node/http') -const FQDN = await partnersFqdn() +const FQDN = await appManagementFqdn() const LOGS = '1\\n2\\n3\\n4\\n' const FUNCTION_ERROR = 'function_error' const FUNCTION_RUN = 'function_run' diff --git a/packages/app/src/cli/services/dev/fetch.test.ts b/packages/app/src/cli/services/dev/fetch.test.ts index 9c23e0a650e..479b5b89798 100644 --- a/packages/app/src/cli/services/dev/fetch.test.ts +++ b/packages/app/src/cli/services/dev/fetch.test.ts @@ -43,8 +43,9 @@ afterEach(() => { }) describe('fetchOrganizations', async () => { - test('returns fetched organizations from Partners and App Management', async () => { + test('returns fetched organizations from Partners and App Management for 1P development', async () => { // Given + vi.stubEnv('SHOPIFY_CLI_1P_DEV', 'true') const partnersClient: PartnersClient = testDeveloperPlatformClient({ organizations: () => Promise.resolve([ORG1]), }) as PartnersClient @@ -63,15 +64,27 @@ describe('fetchOrganizations', async () => { expect(appManagementClient.organizations).toHaveBeenCalled() }) + test('returns fetched organizations from App Management for 3P development', async () => { + // Given + const appManagementClient: AppManagementClient = testDeveloperPlatformClient({ + organizations: () => Promise.resolve([ORG2]), + }) as AppManagementClient + vi.mocked(AppManagementClient.getInstance).mockReturnValue(appManagementClient) + + // When + const got = await fetchOrganizations() + + // Then + expect(got).toEqual([ORG2]) + expect(PartnersClient.getInstance).not.toHaveBeenCalled() + expect(appManagementClient.organizations).toHaveBeenCalled() + }) + test('throws if there are no organizations', async () => { // Given - const partnersClient: PartnersClient = testDeveloperPlatformClient({ - organizations: () => Promise.resolve([]), - }) as PartnersClient const appManagementClient: AppManagementClient = testDeveloperPlatformClient({ organizations: () => Promise.resolve([]), }) as AppManagementClient - vi.mocked(PartnersClient.getInstance).mockReturnValue(partnersClient) vi.mocked(AppManagementClient.getInstance).mockReturnValue(appManagementClient) // When @@ -79,7 +92,6 @@ describe('fetchOrganizations', async () => { // Then await expect(got).rejects.toThrow('No Organization found') - expect(partnersClient.organizations).toHaveBeenCalled() expect(appManagementClient.organizations).toHaveBeenCalled() }) }) diff --git a/packages/app/src/cli/utilities/developer-platform-client.ts b/packages/app/src/cli/utilities/developer-platform-client.ts index 476e879b178..a919f8e00e6 100644 --- a/packages/app/src/cli/utilities/developer-platform-client.ts +++ b/packages/app/src/cli/utilities/developer-platform-client.ts @@ -96,7 +96,7 @@ export function selectDeveloperPlatformClient({ organization, }: SelectDeveloperPlatformClientOptions = {}): DeveloperPlatformClient { if (organization) return selectDeveloperPlatformClientByOrg(organization) - return PartnersClient.getInstance() + return defaultDeveloperPlatformClient() } function selectDeveloperPlatformClientByOrg(organization: Organization): DeveloperPlatformClient { @@ -104,6 +104,12 @@ function selectDeveloperPlatformClientByOrg(organization: Organization): Develop return PartnersClient.getInstance() } +function defaultDeveloperPlatformClient(): DeveloperPlatformClient { + if (blockPartnersAccess()) return AppManagementClient.getInstance() + + return PartnersClient.getInstance() +} + export interface CreateAppOptions { name: string isLaunchable?: boolean 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 7159e051fc7..c867540fc31 100644 --- a/packages/cli-kit/src/public/node/context/fqdn.test.ts +++ b/packages/cli-kit/src/public/node/context/fqdn.test.ts @@ -8,9 +8,11 @@ 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 { @@ -32,6 +34,7 @@ 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() @@ -43,6 +46,7 @@ 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() diff --git a/packages/cli-kit/src/public/node/context/fqdn.ts b/packages/cli-kit/src/public/node/context/fqdn.ts index 483372e5135..c45d1999c64 100644 --- a/packages/cli-kit/src/public/node/context/fqdn.ts +++ b/packages/cli-kit/src/public/node/context/fqdn.ts @@ -14,7 +14,7 @@ export const NotProvidedStoreFQDNError = new AbortError( */ export async function partnersFqdn(): Promise { if (blockPartnersAccess()) { - throw new BugError('Partners API is blocked by the SHOPIFY_CLI_NEVER_USE_PARTNERS_API environment variable.') + throw new BugError('Partners API is is no longer available.') } const environment = serviceEnvironment() const productionFqdn = 'partners.shopify.com' diff --git a/packages/cli-kit/src/public/node/environment.ts b/packages/cli-kit/src/public/node/environment.ts index 1300fb7afb4..5e5b40a8c7e 100644 --- a/packages/cli-kit/src/public/node/environment.ts +++ b/packages/cli-kit/src/public/node/environment.ts @@ -86,10 +86,13 @@ export function jsonOutputEnabled(environment = getEnvironmentVariables()): bool /** * If true, the CLI should not use the Partners API. * - * @returns True if the SHOPIFY_CLI_NEVER_USE_PARTNERS_API environment variable is set. + * @returns True when SHOPIFY_CLI_NEVER_USE_PARTNERS_API is set or SHOPIFY_CLI_1P_DEV is not set. */ export function blockPartnersAccess(): boolean { - return isTruthy(getEnvironmentVariables()[environmentVariables.neverUsePartnersApi]) + return ( + isTruthy(getEnvironmentVariables()[environmentVariables.neverUsePartnersApi]) || + !isTruthy(getEnvironmentVariables()[environmentVariables.firstPartyDev]) + ) } /**