diff --git a/.changeset/app-info-organization.md b/.changeset/app-info-organization.md new file mode 100644 index 00000000000..9ad7d7bba21 --- /dev/null +++ b/.changeset/app-info-organization.md @@ -0,0 +1,5 @@ +--- +'@shopify/app': minor +--- + +Show the organization name and ID in `app info` diff --git a/packages/app/src/cli/services/info.test.ts b/packages/app/src/cli/services/info.test.ts index 2b7acb04be0..354741b7e77 100644 --- a/packages/app/src/cli/services/info.test.ts +++ b/packages/app/src/cli/services/info.test.ts @@ -265,6 +265,34 @@ describe('info', () => { expect(rawResult.usesWorkspaces).toBe(false) }) }) + + test('returns the organization name and ID using the default output format', async () => { + await inTemporaryDirectory(async (tmp) => { + // Given + const app = mockApp({directory: tmp}) + + // When + const result = (await info(app, remoteApp, ORG1, testProject(), infoOptions())) as AlertCustomSection[] + const configData = tabularDataSectionFromInfo(result, 'CURRENT APP CONFIGURATION\n') + + // Then + expect(configData).toContainEqual(['Organization', 'test (123)']) + }) + }) + + test('returns the organization name and ID using the json output format', async () => { + await inTemporaryDirectory(async (tmp) => { + // Given + const app = mockApp({directory: tmp}) + + // When + const result = await info(app, remoteApp, ORG1, testProject(), {...infoOptions(), format: 'json'}) + + // Then + const resultObject = JSON.parse((result as TokenizedString).value) + expect(resultObject.organization).toEqual({id: '123', businessName: 'test'}) + }) + }) }) function mockApp({ diff --git a/packages/app/src/cli/services/info.ts b/packages/app/src/cli/services/info.ts index b616c4ab583..e08bbc1e5d1 100644 --- a/packages/app/src/cli/services/info.ts +++ b/packages/app/src/cli/services/info.ts @@ -37,7 +37,7 @@ export async function info( if (options.webEnv) { return infoWeb(app, remoteApp, organization, options) } else { - return infoApp(app, remoteApp, project, options) + return infoApp(app, remoteApp, organization, project, options) } } @@ -53,6 +53,7 @@ async function infoWeb( async function infoApp( app: AppLinkedInterface, remoteApp: OrganizationApp, + organization: Organization, project: Project, options: InfoOptions, ): Promise { @@ -63,6 +64,7 @@ async function infoApp( packageManager: project.packageManager, nodeDependencies: project.nodeDependencies, usesWorkspaces: project.usesWorkspaces, + organization: {id: organization.id, businessName: organization.businessName}, allExtensions: extensionsInfo, } if ('realExtensions' in appWithSupportedExtensions) { @@ -88,7 +90,7 @@ async function infoApp( 2, )}` } else { - const appInfo = new AppInfo(app, remoteApp, project, options) + const appInfo = new AppInfo(app, remoteApp, organization, project, options) return appInfo.output() } } @@ -120,12 +122,20 @@ const NOT_LOADED_TEXT = 'NOT LOADED' class AppInfo { private readonly app: AppLinkedInterface private readonly remoteApp: OrganizationApp + private readonly organization: Organization private readonly project: Project private readonly options: InfoOptions - constructor(app: AppLinkedInterface, remoteApp: OrganizationApp, project: Project, options: InfoOptions) { + constructor( + app: AppLinkedInterface, + remoteApp: OrganizationApp, + organization: Organization, + project: Project, + options: InfoOptions, + ) { this.app = app this.remoteApp = remoteApp + this.organization = organization this.project = project this.options = options } @@ -160,6 +170,7 @@ class AppInfo { ['Configuration file', {filePath: basename(this.app.configPath) || configurationFileNames.app}], ['App name', this.remoteApp.title ? {userInput: this.remoteApp.title} : NOT_CONFIGURED_TOKEN], ['Client ID', this.remoteApp.apiKey || NOT_CONFIGURED_TOKEN], + ['Organization', `${this.organization.businessName} (${this.organization.id})`], ['Access scopes', getAppScopes(this.app.configuration)], [ 'Dev store',