From 04f35fd9e13c2c372aca563ae3733ba9a4b2ab17 Mon Sep 17 00:00:00 2001 From: Donald Merand Date: Fri, 5 Jun 2026 10:23:48 -0400 Subject: [PATCH] Add store-auth source and auto fallback to store list Adds `--from auto | organization | store-auth` (default auto). `auto` prefers the Shopify organization and falls back to locally stored store auth on any listing failure; `--from organization` stays strict and surfaces the error. The store-auth source renders Subdomain | Connected. Threads noPrompt through ensureAuthenticatedBusinessPlatform so auto can probe without prompting. --- .changeset/store-list-bp-auto.md | 2 +- .../interfaces/store-list.interface.ts | 6 + .../generated/generated_docs_data_v2.json | 11 +- .../cli-kit/src/public/node/session.test.ts | 15 ++ packages/cli-kit/src/public/node/session.ts | 8 +- packages/cli/README.md | 28 +++- packages/cli/oclif.manifest.json | 23 ++- .../store/src/cli/commands/store/list.test.ts | 20 +-- packages/store/src/cli/commands/store/list.ts | 34 +++- .../src/cli/services/store/auth/index.ts | 2 +- .../cli/services/store/auth/stored-auth.ts | 2 +- .../cli/services/store/list/bp-source.test.ts | 119 ++++++-------- .../src/cli/services/store/list/bp-source.ts | 152 ++++++++++-------- .../src/cli/services/store/list/index.test.ts | 109 ++++++++++--- .../src/cli/services/store/list/index.ts | 56 ++++++- .../services/store/list/local-source.test.ts | 42 +++++ .../cli/services/store/list/local-source.ts | 11 ++ .../cli/services/store/list/result.test.ts | 66 +++++++- .../src/cli/services/store/list/result.ts | 52 ++++-- .../src/cli/services/store/list/types.ts | 28 +++- 20 files changed, 575 insertions(+), 211 deletions(-) create mode 100644 packages/store/src/cli/services/store/list/local-source.test.ts create mode 100644 packages/store/src/cli/services/store/list/local-source.ts diff --git a/.changeset/store-list-bp-auto.md b/.changeset/store-list-bp-auto.md index f9843d66dc..c77c4b49a6 100644 --- a/.changeset/store-list-bp-auto.md +++ b/.changeset/store-list-bp-auto.md @@ -5,4 +5,4 @@ '@shopify/cli-kit': patch --- -Add `shopify store list` to list stores from Business Platform for the current Shopify CLI account. When some organization-scoped Business Platform lookups fail, the command now returns successful organizations with a warning and failure details for the skipped organizations. +Add `shopify store list` with `--from auto|organization|store-auth`. By default the command prefers your Shopify organization and falls back to locally stored store auth when the organization can't be listed for the current CLI session. When some organization lookups fail, the command still returns successful organizations with a warning and failure details for the skipped organizations. diff --git a/docs-shopify.dev/commands/interfaces/store-list.interface.ts b/docs-shopify.dev/commands/interfaces/store-list.interface.ts index a4e9b1420b..f49780278a 100644 --- a/docs-shopify.dev/commands/interfaces/store-list.interface.ts +++ b/docs-shopify.dev/commands/interfaces/store-list.interface.ts @@ -4,6 +4,12 @@ * @publicDocs */ export interface storelist { + /** + * Source for the listing. `auto` prefers your Shopify organization and falls back to locally stored store auth when necessary. + * @environment SHOPIFY_FLAG_STORE_LIST_FROM + */ + '--from '?: string + /** * Output the result as JSON. Automatically disables color output. * @environment SHOPIFY_FLAG_JSON diff --git a/docs-shopify.dev/generated/generated_docs_data_v2.json b/docs-shopify.dev/generated/generated_docs_data_v2.json index 3ca54e2028..9ac1a2c6cb 100644 --- a/docs-shopify.dev/generated/generated_docs_data_v2.json +++ b/docs-shopify.dev/generated/generated_docs_data_v2.json @@ -4300,6 +4300,15 @@ "description": "The following flags are available for the `store list` command:", "isPublicDocs": true, "members": [ + { + "filePath": "docs-shopify.dev/commands/interfaces/store-list.interface.ts", + "syntaxKind": "PropertySignature", + "name": "--from ", + "value": "string", + "description": "Source for the listing. `auto` prefers your Shopify organization and falls back to locally stored store auth when necessary.", + "isOptional": true, + "environmentValue": "SHOPIFY_FLAG_STORE_LIST_FROM" + }, { "filePath": "docs-shopify.dev/commands/interfaces/store-list.interface.ts", "syntaxKind": "PropertySignature", @@ -4328,7 +4337,7 @@ "environmentValue": "SHOPIFY_FLAG_JSON" } ], - "value": "export interface storelist {\n /**\n * Output the result as JSON. Automatically disables color output.\n * @environment SHOPIFY_FLAG_JSON\n */\n '-j, --json'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" + "value": "export interface storelist {\n /**\n * Source for the listing. `auto` prefers your Shopify organization and falls back to locally stored store auth when necessary.\n * @environment SHOPIFY_FLAG_STORE_LIST_FROM\n */\n '--from '?: string\n\n /**\n * Output the result as JSON. Automatically disables color output.\n * @environment SHOPIFY_FLAG_JSON\n */\n '-j, --json'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" } }, "themecheck": { diff --git a/packages/cli-kit/src/public/node/session.test.ts b/packages/cli-kit/src/public/node/session.test.ts index 810f9acc1c..ef689ec210 100644 --- a/packages/cli-kit/src/public/node/session.test.ts +++ b/packages/cli-kit/src/public/node/session.test.ts @@ -216,6 +216,21 @@ describe('ensureAuthenticatedBusinessPlatform', () => { expect(got).toEqual('business_platform') }) + test('passes auth options through to the private auth helper', async () => { + // Given + vi.mocked(ensureAuthenticated).mockResolvedValueOnce({businessPlatform: 'business_platform', userId: '1234-5678'}) + + // When + await ensureAuthenticatedBusinessPlatform([], {noPrompt: true}) + + // Then + expect(ensureAuthenticated).toHaveBeenCalledWith( + {businessPlatformApi: {scopes: []}}, + process.env, + expect.objectContaining({noPrompt: true}), + ) + }) + test('throws error if there is no business_platform token', async () => { // Given vi.mocked(ensureAuthenticated).mockResolvedValueOnce({partners: 'partners_token', userId: '1234-5678'}) diff --git a/packages/cli-kit/src/public/node/session.ts b/packages/cli-kit/src/public/node/session.ts index 1ebffdeaf4..630626ecd9 100644 --- a/packages/cli-kit/src/public/node/session.ts +++ b/packages/cli-kit/src/public/node/session.ts @@ -270,13 +270,17 @@ ${outputToken.json(scopes)} * Ensure that we have a valid session to access the Business Platform API. * * @param scopes - Optional array of extra scopes to authenticate with. + * @param options - Optional auth behavior overrides such as `noPrompt`. * @returns The access token for the Business Platform API. */ -export async function ensureAuthenticatedBusinessPlatform(scopes: BusinessPlatformScope[] = []): Promise { +export async function ensureAuthenticatedBusinessPlatform( + scopes: BusinessPlatformScope[] = [], + options: EnsureAuthenticatedAdditionalOptions = {}, +): Promise { outputDebug(outputContent`Ensuring that the user is authenticated with the Business Platform API with the following scopes: ${outputToken.json(scopes)} `) - const tokens = await ensureAuthenticated({businessPlatformApi: {scopes}}, process.env) + const tokens = await ensureAuthenticated({businessPlatformApi: {scopes}}, process.env, options) if (!tokens.businessPlatform) { throw new BugError('No business-platform token found after ensuring authenticated') } diff --git a/packages/cli/README.md b/packages/cli/README.md index 9632471b40..a676a67696 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -2182,25 +2182,39 @@ EXAMPLES ## `shopify store list` -List stores in your Shopify organization. +List stores available to the current CLI session. ``` USAGE - $ shopify store list [-j] [--no-color] [--verbose] + $ shopify store list [--from auto|organization|store-auth] [-j] [--no-color] [--verbose] FLAGS - -j, --json [env: SHOPIFY_FLAG_JSON] Output the result as JSON. Automatically disables color output. - --no-color [env: SHOPIFY_FLAG_NO_COLOR] Disable color output. - --verbose [env: SHOPIFY_FLAG_VERBOSE] Increase the verbosity of the output. + -j, --json [env: SHOPIFY_FLAG_JSON] Output the result as JSON. Automatically disables color output. + --from=