diff --git a/packages/app/src/cli/commands/app/function/schema.test.ts b/packages/app/src/cli/commands/app/function/schema.test.ts new file mode 100644 index 00000000000..f724a674cff --- /dev/null +++ b/packages/app/src/cli/commands/app/function/schema.test.ts @@ -0,0 +1,83 @@ +import FetchSchema from './schema.js' +import {linkedAppContext} from '../../../services/app-context.js' +import {generateSchemaService} from '../../../services/generate-schema.js' +import { + testAppWithConfig, + testDeveloperPlatformClient, + testFunctionExtension, + testOrganization, + testOrganizationApp, + testProject, +} from '../../../models/app/app.test-data.js' +import {inTemporaryDirectory} from '@shopify/cli-kit/node/fs' +import {describe, expect, test, vi} from 'vitest' + +vi.mock('../../../services/app-context.js') +vi.mock('../../../services/generate-schema.js') + +describe('app function schema command', () => { + test.each([ + { + name: 'explicit client ID and stdout', + flags: ['--client-id', 'selected-client-id', '--stdout'], + clientId: 'selected-client-id', + userProvidedConfigName: undefined, + forceRelink: false, + stdout: true, + }, + { + name: 'config and file output', + flags: ['--config', 'staging'], + clientId: undefined, + userProvidedConfigName: 'staging', + forceRelink: false, + stdout: false, + }, + { + name: 'reset and file output', + flags: ['--reset'], + clientId: undefined, + userProvidedConfigName: undefined, + forceRelink: true, + stdout: false, + }, + ])('uses the selected remote app ID with $name', async (scenario) => { + await inTemporaryDirectory(async (directory) => { + const extension = await testFunctionExtension({dir: directory}) + const app = testAppWithConfig({app: {allExtensions: [extension]}, config: {client_id: 'local-client-id'}}) + const remoteApp = testOrganizationApp({ + id: 'gid://shopify/App/987', + apiKey: 'remote-client-id', + organizationId: '417', + }) + const organization = {...testOrganization(), id: '417'} + const developerPlatformClient = testDeveloperPlatformClient() + vi.mocked(linkedAppContext).mockResolvedValue({ + app, + remoteApp, + organization, + developerPlatformClient, + specifications: [], + project: testProject(), + activeConfig: {} as never, + }) + + const result = await FetchSchema.run([...scenario.flags, '--path', directory], import.meta.url) + + expect(linkedAppContext).toHaveBeenCalledWith({ + directory, + clientId: scenario.clientId, + forceRelink: scenario.forceRelink, + userProvidedConfigName: scenario.userProvidedConfigName, + }) + expect(generateSchemaService).toHaveBeenCalledWith({ + appId: remoteApp.id, + extension, + stdout: scenario.stdout, + developerPlatformClient, + orgId: organization.id, + }) + expect(result).toEqual({app}) + }) + }) +}) diff --git a/packages/app/src/cli/commands/app/function/schema.ts b/packages/app/src/cli/commands/app/function/schema.ts index e98a62810c2..6850b3ed51a 100644 --- a/packages/app/src/cli/commands/app/function/schema.ts +++ b/packages/app/src/cli/commands/app/function/schema.ts @@ -30,7 +30,7 @@ export default class FetchSchema extends AppLinkedCommand { public async run(): Promise { const {flags} = await this.parse(FetchSchema) - const {app, developerPlatformClient, organization} = await linkedAppContext({ + const {app, remoteApp, developerPlatformClient, organization} = await linkedAppContext({ directory: flags.path, clientId: flags['client-id'], forceRelink: flags.reset, @@ -40,7 +40,7 @@ export default class FetchSchema extends AppLinkedCommand { const ourFunction = await chooseFunction(app, flags.path) await generateSchemaService({ - app, + appId: remoteApp.id, extension: ourFunction, stdout: flags.stdout, developerPlatformClient, diff --git a/packages/app/src/cli/models/app/app.test-data.ts b/packages/app/src/cli/models/app/app.test-data.ts index 935e9ea5c17..5062c1631a7 100644 --- a/packages/app/src/cli/models/app/app.test-data.ts +++ b/packages/app/src/cli/models/app/app.test-data.ts @@ -1363,9 +1363,9 @@ export function testDeveloperPlatformClient( migrateFlowExtension: (_input: MigrateFlowExtensionVariables) => Promise.resolve(migrateFlowExtensionResponse), migrateAppModule: (_input: MigrateAppModuleVariables) => Promise.resolve(migrateAppModuleResponse), updateURLs: (_input: UpdateURLsVariables) => Promise.resolve(updateURLsResponse), - targetSchemaDefinition: (_input: SchemaDefinitionByTargetQueryVariables & {apiKey?: string}, _orgId: string) => + targetSchemaDefinition: (_input: SchemaDefinitionByTargetQueryVariables, _appId: string, _orgId: string) => Promise.resolve('schema'), - apiSchemaDefinition: (_input: SchemaDefinitionByApiTypeQueryVariables & {apiKey?: string}, _orgId: string) => + apiSchemaDefinition: (_input: SchemaDefinitionByApiTypeQueryVariables, _appId: string, _orgId: string) => Promise.resolve('schema'), migrateToUiExtension: (_input: MigrateToUiExtensionVariables) => Promise.resolve(migrateToUiExtensionResponse), toExtensionGraphQLType: (input: string) => input, diff --git a/packages/app/src/cli/services/function/common.test.ts b/packages/app/src/cli/services/function/common.test.ts index e56e81673a4..3aaa6c5665d 100644 --- a/packages/app/src/cli/services/function/common.test.ts +++ b/packages/app/src/cli/services/function/common.test.ts @@ -10,7 +10,6 @@ import {AppLinkedInterface} from '../../models/app/app.js' import {ExtensionInstance} from '../../models/extensions/extension-instance.js' import {FunctionConfigType} from '../../models/extensions/specifications/function.js' import {generateSchemaService} from '../generate-schema.js' -import {DeveloperPlatformClient} from '../../utilities/developer-platform-client.js' import {linkedAppContext} from '../app-context.js' import {describe, vi, expect, beforeEach, test} from 'vitest' import {renderAutocompletePrompt, renderFatalError} from '@shopify/cli-kit/node/ui' @@ -33,7 +32,7 @@ beforeEach(async () => { app = testAppLinked({allExtensions: [ourFunction]}) vi.mocked(linkedAppContext).mockResolvedValue({ app, - remoteApp: testOrganizationApp(), + remoteApp: testOrganizationApp({id: 'gid://shopify/App/731', apiKey: 'remote-client-id'}), developerPlatformClient: testDeveloperPlatformClient(), specifications: [], organization: testOrganization(), @@ -47,10 +46,8 @@ beforeEach(async () => { describe('getOrGenerateSchemaPath', () => { let app: AppLinkedInterface - let developerPlatformClient: DeveloperPlatformClient beforeEach(() => { app = testAppLinked() - developerPlatformClient = testDeveloperPlatformClient() }) test('returns the path if the schema file exists', async () => { @@ -69,6 +66,8 @@ describe('getOrGenerateSchemaPath', () => { // Then expect(result).toBe(expectedPath) + expect(linkedAppContext).not.toHaveBeenCalled() + expect(generateSchemaService).not.toHaveBeenCalled() }) }) @@ -91,6 +90,38 @@ describe('getOrGenerateSchemaPath', () => { // Then expect(result).toBe(expectedPath) + expect(linkedAppContext).toHaveBeenCalledWith({ + directory: app.directory, + clientId: '123', + forceRelink: false, + userProvidedConfigName: undefined, + }) + expect(generateSchemaService).toHaveBeenCalledWith({ + appId: 'gid://shopify/App/731', + developerPlatformClient: expect.anything(), + extension, + stdout: false, + orgId: '1', + }) + }) + }) + + test('returns undefined when the fetched schema is not written', async () => { + await inTemporaryDirectory(async (tmpDir) => { + const extension = {directory: tmpDir} as ExtensionInstance + + const result = await getOrGenerateSchemaPath(extension, app.directory, undefined, true, 'staging') + + expect(result).toBeUndefined() + expect(linkedAppContext).toHaveBeenCalledWith({ + directory: app.directory, + clientId: undefined, + forceRelink: true, + userProvidedConfigName: 'staging', + }) + expect(generateSchemaService).toHaveBeenCalledWith( + expect.objectContaining({appId: 'gid://shopify/App/731', extension, stdout: false}), + ) }) }) }) diff --git a/packages/app/src/cli/services/function/common.ts b/packages/app/src/cli/services/function/common.ts index 07137a90988..ae8491c2744 100644 --- a/packages/app/src/cli/services/function/common.ts +++ b/packages/app/src/cli/services/function/common.ts @@ -53,7 +53,7 @@ export async function getOrGenerateSchemaPath( return path } - const {app, developerPlatformClient, organization} = await linkedAppContext({ + const {remoteApp, developerPlatformClient, organization} = await linkedAppContext({ directory: appDirectory, clientId, forceRelink, @@ -61,7 +61,7 @@ export async function getOrGenerateSchemaPath( }) await generateSchemaService({ - app, + appId: remoteApp.id, developerPlatformClient, extension, stdout: false, diff --git a/packages/app/src/cli/services/generate-schema.test.ts b/packages/app/src/cli/services/generate-schema.test.ts index 9c3adc1309d..804914a2c60 100644 --- a/packages/app/src/cli/services/generate-schema.test.ts +++ b/packages/app/src/cli/services/generate-schema.test.ts @@ -1,8 +1,8 @@ import {generateSchemaService} from './generate-schema.js' -import {testAppLinked, testDeveloperPlatformClient, testFunctionExtension} from '../models/app/app.test-data.js' +import {testDeveloperPlatformClient, testFunctionExtension} from '../models/app/app.test-data.js' import {describe, expect, vi, test} from 'vitest' import {AbortError} from '@shopify/cli-kit/node/error' -import {inTemporaryDirectory, readFile, mkdir} from '@shopify/cli-kit/node/fs' +import {inTemporaryDirectory, readFile} from '@shopify/cli-kit/node/fs' import {joinPath} from '@shopify/cli-kit/node/path' import * as output from '@shopify/cli-kit/node/output' @@ -28,17 +28,14 @@ describe('generateSchemaService', () => { await inTemporaryDirectory(async (tmpDir) => { // Given const orgId = 'test' - const extensionDir = joinPath(tmpDir, 'extensions', 'my-function') - await mkdir(extensionDir) - - const app = testAppLinked() + const appId = 'gid://shopify/App/42' const extension = await testFunctionExtension({ dir: tmpDir, }) // When await generateSchemaService({ - app, + appId, extension, stdout: false, developerPlatformClient: testDeveloperPlatformClient(), @@ -54,9 +51,8 @@ describe('generateSchemaService', () => { test('Print the latest GraphQL schema to stdout when stdout flag is PRESENT', async () => { await inTemporaryDirectory(async (tmpDir) => { // Given - const app = testAppLinked() - const extension = await testFunctionExtension() - const path = tmpDir + const appId = 'gid://shopify/App/42' + const extension = await testFunctionExtension({dir: tmpDir}) const stdout = true const orgId = '123' const mockOutput = vi.fn() @@ -64,7 +60,7 @@ describe('generateSchemaService', () => { // When await generateSchemaService({ - app, + appId, extension, stdout, developerPlatformClient: testDeveloperPlatformClient(), @@ -79,10 +75,7 @@ describe('generateSchemaService', () => { describe('GraphQL query', () => { test('Uses ApiSchemaDefinitionQuery when not using targets', async () => { await inTemporaryDirectory(async (tmpDir) => { - const extensionDir = joinPath(tmpDir, 'extensions', 'my-function') - await mkdir(extensionDir) - - const app = testAppLinked() + const appId = 'gid://shopify/App/731' const extension = await testFunctionExtension({ dir: tmpDir, config: { @@ -99,12 +92,11 @@ describe('generateSchemaService', () => { }) const orgId = 'test' - const path = tmpDir const version = extension.configuration.api_version const developerPlatformClient = testDeveloperPlatformClient() await generateSchemaService({ - app, + appId, extension, stdout: false, developerPlatformClient, @@ -116,18 +108,16 @@ describe('generateSchemaService', () => { version, type: extension.configuration.type, }, - app.configuration.client_id, + appId, orgId, ) + expect(developerPlatformClient.targetSchemaDefinition).not.toHaveBeenCalled() }) }) test('Uses TargetSchemaDefinitionQuery when targets present', async () => { await inTemporaryDirectory(async (tmpDir) => { - const extensionDir = joinPath(tmpDir, 'extensions', 'my-function') - await mkdir(extensionDir) - - const app = testAppLinked() + const appId = 'gid://shopify/App/732' const extension = await testFunctionExtension({ dir: tmpDir, config: { @@ -157,7 +147,7 @@ describe('generateSchemaService', () => { const developerPlatformClient = testDeveloperPlatformClient() await generateSchemaService({ - app, + appId, extension, stdout: false, developerPlatformClient, @@ -169,16 +159,17 @@ describe('generateSchemaService', () => { handle: expectedTarget, version, }, - app.configuration.client_id, + appId, orgId, ) + expect(developerPlatformClient.apiSchemaDefinition).not.toHaveBeenCalled() }) }) }) test('aborts if a schema could not be generated', async () => { // Given - const app = testAppLinked() + const appId = 'gid://shopify/App/42' const extension = await testFunctionExtension() const orgId = '123' const developerPlatformClient = testDeveloperPlatformClient({ @@ -187,7 +178,7 @@ describe('generateSchemaService', () => { // When const result = generateSchemaService({ - app, + appId, extension, stdout: true, developerPlatformClient, @@ -196,5 +187,40 @@ describe('generateSchemaService', () => { // Then await expect(result).rejects.toThrow(AbortError) + await expect(result).rejects.toThrow(`A schema could not be generated for ${extension.localIdentifier}`) + }) + + test('aborts if a target schema could not be generated', async () => { + const appId = 'gid://shopify/App/732' + const extension = await testFunctionExtension({ + config: { + name: 'test function extension', + description: 'description', + type: 'function', + targeting: [{target: 'cart.transform.run'}], + build: {command: 'echo "hello world"', wasm_opt: true}, + api_version: '2025-07', + configuration_ui: true, + }, + }) + const developerPlatformClient = testDeveloperPlatformClient({ + targetSchemaDefinition: () => Promise.resolve(null), + }) + + const result = generateSchemaService({ + appId, + extension, + stdout: true, + developerPlatformClient, + orgId: '123', + }) + + await expect(result).rejects.toThrow(AbortError) + await expect(result).rejects.toThrow(`A schema could not be generated for ${extension.localIdentifier}`) + expect(developerPlatformClient.targetSchemaDefinition).toHaveBeenCalledWith( + {handle: 'cart.transform.run', version: '2025-07'}, + appId, + '123', + ) }) }) diff --git a/packages/app/src/cli/services/generate-schema.ts b/packages/app/src/cli/services/generate-schema.ts index f5316abadf1..bee9839d5f2 100644 --- a/packages/app/src/cli/services/generate-schema.ts +++ b/packages/app/src/cli/services/generate-schema.ts @@ -4,14 +4,13 @@ import {SchemaDefinitionByApiTypeQueryVariables} from '../api/graphql/functions/ import {SchemaDefinitionByTargetQueryVariables} from '../api/graphql/functions/generated/schema-definition-by-target.js' import {ExtensionInstance} from '../models/extensions/extension-instance.js' import {FunctionConfigType} from '../models/extensions/specifications/function.js' -import {AppLinkedInterface} from '../models/app/app.js' import {AbortError} from '@shopify/cli-kit/node/error' import {outputContent, outputInfo, outputResult} from '@shopify/cli-kit/node/output' import {writeFile} from '@shopify/cli-kit/node/fs' import {joinPath} from '@shopify/cli-kit/node/path' interface GenerateSchemaOptions { - app: AppLinkedInterface + appId: string extension: ExtensionInstance stdout: boolean developerPlatformClient: DeveloperPlatformClient @@ -19,16 +18,14 @@ interface GenerateSchemaOptions { } export async function generateSchemaService(options: GenerateSchemaOptions) { - const {extension, stdout, developerPlatformClient, app, orgId} = options - const apiKey = app.configuration.client_id + const {extension, stdout, developerPlatformClient, appId, orgId} = options const {api_version: version, type, targeting} = extension.configuration const usingTargets = Boolean(targeting?.length) const fetchedDefinition = await (usingTargets ? generateSchemaFromTarget({ localIdentifier: extension.localIdentifier, developerPlatformClient, - apiKey, - + appId, target: targeting![0]!.target, version, orgId, @@ -36,7 +33,7 @@ export async function generateSchemaService(options: GenerateSchemaOptions) { : generateSchemaFromApiType({ localIdentifier: extension.localIdentifier, developerPlatformClient, - apiKey, + appId, type, version, orgId, @@ -56,7 +53,7 @@ export async function generateSchemaService(options: GenerateSchemaOptions) { interface BaseGenerateSchemaOptions { localIdentifier: string developerPlatformClient: DeveloperPlatformClient - apiKey: string + appId: string version: string orgId: string } @@ -68,7 +65,7 @@ interface GenerateSchemaFromTargetOptions extends BaseGenerateSchemaOptions { async function generateSchemaFromTarget({ localIdentifier, developerPlatformClient, - apiKey, + appId, target, version, orgId, @@ -77,8 +74,7 @@ async function generateSchemaFromTarget({ handle: target, version, } - // Api key required for partners reqs, can be removed once fully migrated to AMF - const definition = await developerPlatformClient.targetSchemaDefinition(variables, apiKey, orgId) + const definition = await developerPlatformClient.targetSchemaDefinition(variables, appId, orgId) if (!definition) { throw new AbortError( @@ -97,7 +93,7 @@ interface GenerateSchemaFromType extends BaseGenerateSchemaOptions { async function generateSchemaFromApiType({ localIdentifier, developerPlatformClient, - apiKey, + appId, version, type, orgId, @@ -107,7 +103,7 @@ async function generateSchemaFromApiType({ type, } - const definition = await developerPlatformClient.apiSchemaDefinition(variables, apiKey, orgId) + const definition = await developerPlatformClient.apiSchemaDefinition(variables, appId, orgId) if (!definition) { throw new AbortError( diff --git a/packages/app/src/cli/utilities/developer-platform-client.ts b/packages/app/src/cli/utilities/developer-platform-client.ts index ac22e68a187..4955b3e1580 100644 --- a/packages/app/src/cli/utilities/developer-platform-client.ts +++ b/packages/app/src/cli/utilities/developer-platform-client.ts @@ -252,12 +252,12 @@ export interface DeveloperPlatformClient { updateURLs: (input: UpdateURLsVariables) => Promise targetSchemaDefinition: ( input: SchemaDefinitionByTargetQueryVariables, - apiKey: string, + appId: string, organizationId: string, ) => Promise apiSchemaDefinition: ( input: SchemaDefinitionByApiTypeQueryVariables, - apiKey: string, + appId: string, organizationId: string, ) => Promise toExtensionGraphQLType: (input: string) => string diff --git a/packages/app/src/cli/utilities/developer-platform-client/app-management-client.test.ts b/packages/app/src/cli/utilities/developer-platform-client/app-management-client.test.ts index 47c085ac351..841d649e386 100644 --- a/packages/app/src/cli/utilities/developer-platform-client/app-management-client.test.ts +++ b/packages/app/src/cli/utilities/developer-platform-client/app-management-client.test.ts @@ -19,6 +19,8 @@ import { } from '../../models/app/app.test-data.js' import {ExtensionInstance} from '../../models/extensions/extension-instance.js' import {ListApps} from '../../api/graphql/app-management/generated/apps.js' +import {SchemaDefinitionByTarget} from '../../api/graphql/functions/generated/schema-definition-by-target.js' +import {SchemaDefinitionByApiType} from '../../api/graphql/functions/generated/schema-definition-by-api-type.js' import { FetchStoreByDomain, FetchStoreByDomainQuery, @@ -56,14 +58,16 @@ import { businessPlatformRequestDoc, } from '@shopify/cli-kit/node/api/business-platform' import {appManagementRequestDoc} from '@shopify/cli-kit/node/api/app-management' +import {functionsRequestDoc} from '@shopify/cli-kit/node/api/functions' import {appDevRequestDoc} from '@shopify/cli-kit/node/api/app-dev' -import {BugError} from '@shopify/cli-kit/node/error' +import {AbortError, BugError} from '@shopify/cli-kit/node/error' import {randomUUID} from '@shopify/cli-kit/node/crypto' import {webhooksRequestDoc} from '@shopify/cli-kit/node/api/webhooks' vi.mock('@shopify/cli-kit/node/http') vi.mock('@shopify/cli-kit/node/api/business-platform') vi.mock('@shopify/cli-kit/node/api/app-management') +vi.mock('@shopify/cli-kit/node/api/functions') vi.mock('@shopify/cli-kit/node/api/app-dev') vi.mock('@shopify/organizations') vi.mock('@shopify/cli-kit/node/api/webhooks') @@ -1622,6 +1626,112 @@ describe('AppManagementClient', () => { }) }) +describe('Functions schema definitions', () => { + beforeEach(() => { + vi.mocked(appManagementRequestDoc).mockRejectedValue(new Error('Unexpected App Management app lookup')) + }) + + describe('targetSchemaDefinition', () => { + const app = testOrganizationApp({ + id: 'gid://shopify/App/413', + apiKey: 'client-id-for-target', + organizationId: '9001', + }) + const variables = {handle: 'cart.transform.run', version: '2025-07'} + + test('fetches a definition directly from Functions with the numeric app ID', async () => { + const client = AppManagementClient.getInstance() + client.token = () => Promise.resolve('session-token') + vi.mocked(functionsRequestDoc).mockResolvedValueOnce({target: {api: {schema: {definition: 'target schema'}}}}) + + const definition = await client.targetSchemaDefinition(variables, app.id, app.organizationId) + + expect(definition).toBe('target schema') + expect(functionsRequestDoc).toHaveBeenCalledOnce() + expect(functionsRequestDoc).toHaveBeenCalledWith({ + organizationId: app.organizationId, + query: SchemaDefinitionByTarget, + appId: '413', + variables, + token: 'session-token', + unauthorizedHandler: {type: 'token_refresh', handler: expect.any(Function)}, + }) + expect(appManagementRequestDoc).not.toHaveBeenCalled() + }) + + test('returns null when Functions has no target schema', async () => { + const client = AppManagementClient.getInstance() + client.token = () => Promise.resolve('session-token') + vi.mocked(functionsRequestDoc).mockResolvedValueOnce({target: {api: {schema: null}}}) + + await expect(client.targetSchemaDefinition(variables, app.id, app.organizationId)).resolves.toBeNull() + expect(appManagementRequestDoc).not.toHaveBeenCalled() + }) + + test('wraps Functions errors in an AbortError', async () => { + const client = AppManagementClient.getInstance() + client.token = () => Promise.resolve('session-token') + vi.mocked(functionsRequestDoc).mockRejectedValueOnce(new Error('Functions unavailable')) + + const result = client.targetSchemaDefinition(variables, app.id, app.organizationId) + + await expect(result).rejects.toThrow(AbortError) + await expect(result).rejects.toThrow('Failed to fetch schema definition: Error: Functions unavailable') + expect(appManagementRequestDoc).not.toHaveBeenCalled() + }) + }) + + describe('apiSchemaDefinition', () => { + const app = testOrganizationApp({ + id: 'gid://shopify/App/733', + apiKey: 'client-id-for-api-type', + organizationId: '9002', + }) + const variables = {type: 'product_discounts', version: '2025-10'} + + test('fetches a definition directly from Functions with the numeric app ID', async () => { + const client = AppManagementClient.getInstance() + client.token = () => Promise.resolve('session-token') + vi.mocked(functionsRequestDoc).mockResolvedValueOnce({api: {schema: {definition: 'type schema'}}}) + + const definition = await client.apiSchemaDefinition(variables, app.id, app.organizationId) + + expect(definition).toBe('type schema') + expect(functionsRequestDoc).toHaveBeenCalledOnce() + expect(functionsRequestDoc).toHaveBeenCalledWith({ + organizationId: app.organizationId, + query: SchemaDefinitionByApiType, + appId: '733', + variables, + token: 'session-token', + unauthorizedHandler: {type: 'token_refresh', handler: expect.any(Function)}, + }) + expect(appManagementRequestDoc).not.toHaveBeenCalled() + }) + + test('returns null when Functions has no API-type schema', async () => { + const client = AppManagementClient.getInstance() + client.token = () => Promise.resolve('session-token') + vi.mocked(functionsRequestDoc).mockResolvedValueOnce({api: {schema: null}}) + + await expect(client.apiSchemaDefinition(variables, app.id, app.organizationId)).resolves.toBeNull() + expect(appManagementRequestDoc).not.toHaveBeenCalled() + }) + + test('wraps Functions errors in an AbortError', async () => { + const client = AppManagementClient.getInstance() + client.token = () => Promise.resolve('session-token') + vi.mocked(functionsRequestDoc).mockRejectedValueOnce(new Error('Functions unavailable')) + + const result = client.apiSchemaDefinition(variables, app.id, app.organizationId) + + await expect(result).rejects.toThrow(AbortError) + await expect(result).rejects.toThrow('Failed to fetch schema definition: Error: Functions unavailable') + expect(appManagementRequestDoc).not.toHaveBeenCalled() + }) + }) +}) + describe('storeByDomain', () => { test('queries Business Platform with STORE_STATUS=ACTIVE for each requested store type', async () => { // Given diff --git a/packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts b/packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts index a944b75c567..9b08330d38f 100644 --- a/packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts +++ b/packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts @@ -974,12 +974,11 @@ export class AppManagementClient implements DeveloperPlatformClient { async targetSchemaDefinition( input: SchemaDefinitionByTargetQueryVariables, - apiKey: string, + appId: string, organizationId: string, ): Promise { try { - const {app} = await this.activeAppVersionRawResult(apiKey) - const appIdNumber = String(numberFromGid(app.id)) + const appIdNumber = String(numberFromGid(appId)) const result = await this.functionsRequest({ organizationId, query: SchemaDefinitionByTarget, @@ -998,12 +997,11 @@ export class AppManagementClient implements DeveloperPlatformClient { async apiSchemaDefinition( input: SchemaDefinitionByApiTypeQueryVariables, - apiKey: string, + appId: string, organizationId: string, ): Promise { try { - const {app} = await this.activeAppVersionRawResult(apiKey) - const appIdNumber = String(numberFromGid(app.id)) + const appIdNumber = String(numberFromGid(appId)) const result = await this.functionsRequest({ organizationId, query: SchemaDefinitionByApiType,