From 57c26ac9e041a22b4b64e66a4b9161178c50e411 Mon Sep 17 00:00:00 2001 From: Donald Merand Date: Mon, 15 Jun 2026 10:30:28 -0400 Subject: [PATCH 1/3] Add auth list for store auth sessions --- .changeset/auth-list-store-sessions.md | 6 ++ .../interfaces/auth-list.interface.ts | 24 +++++++ packages/cli/README.md | 28 ++++++++ packages/cli/oclif.manifest.json | 50 ++++++++++++++ .../store/src/cli/commands/auth/list.test.ts | 32 +++++++++ packages/store/src/cli/commands/auth/list.ts | 29 ++++++++ .../services/store/auth/list-result.test.ts | 67 +++++++++++++++++++ .../cli/services/store/auth/list-result.ts | 56 ++++++++++++++++ .../src/cli/services/store/auth/list.test.ts | 36 ++++++++++ .../store/src/cli/services/store/auth/list.ts | 31 +++++++++ .../cli/services/store/list/result.test.ts | 3 + .../src/cli/services/store/list/result.ts | 13 +++- packages/store/src/index.ts | 2 + 13 files changed, 375 insertions(+), 2 deletions(-) create mode 100644 .changeset/auth-list-store-sessions.md create mode 100644 docs-shopify.dev/commands/interfaces/auth-list.interface.ts create mode 100644 packages/store/src/cli/commands/auth/list.test.ts create mode 100644 packages/store/src/cli/commands/auth/list.ts create mode 100644 packages/store/src/cli/services/store/auth/list-result.test.ts create mode 100644 packages/store/src/cli/services/store/auth/list-result.ts create mode 100644 packages/store/src/cli/services/store/auth/list.test.ts create mode 100644 packages/store/src/cli/services/store/auth/list.ts diff --git a/.changeset/auth-list-store-sessions.md b/.changeset/auth-list-store-sessions.md new file mode 100644 index 00000000000..4ebb8630e60 --- /dev/null +++ b/.changeset/auth-list-store-sessions.md @@ -0,0 +1,6 @@ +--- +'@shopify/cli': minor +'@shopify/store': minor +--- + +Add `shopify auth list` to list stores authenticated directly with `shopify store auth`. diff --git a/docs-shopify.dev/commands/interfaces/auth-list.interface.ts b/docs-shopify.dev/commands/interfaces/auth-list.interface.ts new file mode 100644 index 00000000000..efa3d34319d --- /dev/null +++ b/docs-shopify.dev/commands/interfaces/auth-list.interface.ts @@ -0,0 +1,24 @@ +// This is an autogenerated file. Don't edit this file manually. +/** + * The following flags are available for the `auth list` command: + * @publicDocs + */ +export interface authlist { + /** + * Output the result as JSON. Automatically disables color output. + * @environment SHOPIFY_FLAG_JSON + */ + '-j, --json'?: '' + + /** + * Disable color output. + * @environment SHOPIFY_FLAG_NO_COLOR + */ + '--no-color'?: '' + + /** + * Increase the verbosity of the output. + * @environment SHOPIFY_FLAG_VERBOSE + */ + '--verbose'?: '' +} diff --git a/packages/cli/README.md b/packages/cli/README.md index 62a97253975..6ac7ea8e666 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -30,6 +30,7 @@ * [`shopify app release --version `](#shopify-app-release---version-version) * [`shopify app versions list`](#shopify-app-versions-list) * [`shopify app webhook trigger`](#shopify-app-webhook-trigger) +* [`shopify auth list`](#shopify-auth-list) * [`shopify auth login`](#shopify-auth-login) * [`shopify auth logout`](#shopify-auth-logout) * [`shopify commands`](#shopify-commands) @@ -1047,6 +1048,33 @@ DESCRIPTION - You can't use this method to validate your API webhook subscriptions. ``` +## `shopify auth list` + +List stores authenticated directly with store auth. + +``` +USAGE + $ shopify auth list [-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. + +DESCRIPTION + List stores authenticated directly with store auth. + + Lists stores authenticated directly on this machine with `shopify store auth`. + + Use this command to find stores that can be used with store-authenticated commands such as `shopify store execute`. + To list stores in a Shopify organization, run `shopify store list`. + +EXAMPLES + $ shopify auth list + + $ shopify auth list --json +``` + ## `shopify auth login` Logs you in to your Shopify account. diff --git a/packages/cli/oclif.manifest.json b/packages/cli/oclif.manifest.json index 4bff57d73b1..4a91cbba8aa 100644 --- a/packages/cli/oclif.manifest.json +++ b/packages/cli/oclif.manifest.json @@ -3048,6 +3048,56 @@ "strict": true, "summary": "Trigger delivery of a sample webhook topic payload to a designated address." }, + "auth:list": { + "aliases": [ + ], + "args": { + }, + "customPluginName": "@shopify/store", + "description": "Lists stores authenticated directly on this machine with `shopify store auth`.\n\nUse this command to find stores that can be used with store-authenticated commands such as `shopify store execute`.\nTo list stores in a Shopify organization, run `shopify store list`.", + "descriptionWithMarkdown": "Lists stores authenticated directly on this machine with `shopify store auth`.\n\nUse this command to find stores that can be used with store-authenticated commands such as `shopify store execute`.\nTo list stores in a Shopify organization, run `shopify store list`.", + "enableJsonFlag": false, + "examples": [ + "<%= config.bin %> <%= command.id %>", + "<%= config.bin %> <%= command.id %> --json" + ], + "flags": { + "json": { + "allowNo": false, + "char": "j", + "description": "Output the result as JSON. Automatically disables color output.", + "env": "SHOPIFY_FLAG_JSON", + "hidden": false, + "name": "json", + "type": "boolean" + }, + "no-color": { + "allowNo": false, + "description": "Disable color output.", + "env": "SHOPIFY_FLAG_NO_COLOR", + "hidden": false, + "name": "no-color", + "type": "boolean" + }, + "verbose": { + "allowNo": false, + "description": "Increase the verbosity of the output.", + "env": "SHOPIFY_FLAG_VERBOSE", + "hidden": false, + "name": "verbose", + "type": "boolean" + } + }, + "hasDynamicHelp": false, + "hiddenAliases": [ + ], + "id": "auth:list", + "pluginAlias": "@shopify/cli", + "pluginName": "@shopify/cli", + "pluginType": "core", + "strict": true, + "summary": "List stores authenticated directly with store auth." + }, "auth:login": { "aliases": [ ], diff --git a/packages/store/src/cli/commands/auth/list.test.ts b/packages/store/src/cli/commands/auth/list.test.ts new file mode 100644 index 00000000000..5a997090a08 --- /dev/null +++ b/packages/store/src/cli/commands/auth/list.test.ts @@ -0,0 +1,32 @@ +import AuthList from './list.js' +import {listStoreAuthSessions} from '../../services/store/auth/list.js' +import {writeStoreAuthListResult} from '../../services/store/auth/list-result.js' +import {describe, expect, test, vi} from 'vitest' + +vi.mock('../../services/store/auth/list.js') +vi.mock('../../services/store/auth/list-result.js') + +describe('auth list command', () => { + test('lists direct store-auth sessions and writes text output by default', async () => { + vi.mocked(listStoreAuthSessions).mockReturnValue({sessions: []}) + + await AuthList.run([]) + + expect(listStoreAuthSessions).toHaveBeenCalledWith() + expect(writeStoreAuthListResult).toHaveBeenCalledWith({sessions: []}, 'text') + }) + + test('writes json output when requested', async () => { + vi.mocked(listStoreAuthSessions).mockReturnValue({sessions: []}) + + await AuthList.run(['--json']) + + expect(writeStoreAuthListResult).toHaveBeenCalledWith({sessions: []}, 'json') + }) + + test('does not expose organization or source-selection flags', () => { + expect(AuthList.flags.json).toBeDefined() + expect(AuthList.flags).not.toHaveProperty('organization-id') + expect(AuthList.flags).not.toHaveProperty('from') + }) +}) diff --git a/packages/store/src/cli/commands/auth/list.ts b/packages/store/src/cli/commands/auth/list.ts new file mode 100644 index 00000000000..beb42d71e28 --- /dev/null +++ b/packages/store/src/cli/commands/auth/list.ts @@ -0,0 +1,29 @@ +import {listStoreAuthSessions} from '../../services/store/auth/list.js' +import {writeStoreAuthListResult} from '../../services/store/auth/list-result.js' +import Command from '@shopify/cli-kit/node/base-command' +import {globalFlags, jsonFlag} from '@shopify/cli-kit/node/cli' + +export default class AuthList extends Command { + static summary = 'List stores authenticated directly with store auth.' + + static descriptionWithMarkdown = `Lists stores authenticated directly on this machine with \`shopify store auth\`. + +Use this command to find stores that can be used with store-authenticated commands such as \`shopify store execute\`. +To list stores in a Shopify organization, run \`shopify store list\`.` + + static description = this.descriptionWithoutMarkdown() + + static examples = ['<%= config.bin %> <%= command.id %>', '<%= config.bin %> <%= command.id %> --json'] + + static flags = { + ...globalFlags, + ...jsonFlag, + } + + async run(): Promise { + const {flags} = await this.parse(AuthList) + const result = listStoreAuthSessions() + + writeStoreAuthListResult(result, flags.json ? 'json' : 'text') + } +} diff --git a/packages/store/src/cli/services/store/auth/list-result.test.ts b/packages/store/src/cli/services/store/auth/list-result.test.ts new file mode 100644 index 00000000000..ec12e795909 --- /dev/null +++ b/packages/store/src/cli/services/store/auth/list-result.test.ts @@ -0,0 +1,67 @@ +import {writeStoreAuthListResult} from './list-result.js' +import {beforeEach, describe, expect, test} from 'vitest' +import {mockAndCaptureOutput} from '@shopify/cli-kit/node/testing/output' + +describe('writeStoreAuthListResult', () => { + beforeEach(() => { + mockAndCaptureOutput().clear() + }) + + test('renders direct store-auth sessions with subdomain, account, scopes, and connected date', () => { + const output = mockAndCaptureOutput() + + writeStoreAuthListResult( + { + sessions: [ + { + kind: 'store', + store: 'my-shop.myshopify.com', + userId: '42', + scopes: ['read_products', 'write_products'], + connectedAt: '2026-05-22T00:00:00Z', + associatedUser: {id: 42, email: 'merchant@example.com'}, + }, + ], + }, + 'text', + ) + + expect(output.info()).toContain('Stores authenticated directly with `shopify store auth`') + expect(output.info()).toContain('Store') + expect(output.info()).toContain('my-shop') + expect(output.info()).not.toContain('my-shop.myshopify.com') + expect(output.info()).toContain('merchant@example.com') + expect(output.info()).toContain('read_products, write_products') + expect(output.info()).toContain('May 22, 2026') + expect(output.info()).toContain('shopify store list') + }) + + test('renders an empty state with auth and organization-list guidance', () => { + const output = mockAndCaptureOutput() + + writeStoreAuthListResult({sessions: []}, 'text') + + expect(output.info()).toContain('No stores are authenticated directly with `shopify store auth`.') + expect(output.info()).toContain('shopify store auth --store --scopes ') + expect(output.info()).toContain('shopify store list') + }) + + test('writes a deterministic JSON document', () => { + const output = mockAndCaptureOutput() + const result = { + sessions: [ + { + kind: 'store' as const, + store: 'shop.myshopify.com', + userId: '42', + scopes: ['read_products'], + connectedAt: '2026-05-22T00:00:00Z', + }, + ], + } + + writeStoreAuthListResult(result, 'json') + + expect(JSON.parse(output.output())).toEqual(result) + }) +}) diff --git a/packages/store/src/cli/services/store/auth/list-result.ts b/packages/store/src/cli/services/store/auth/list-result.ts new file mode 100644 index 00000000000..b9d6673df29 --- /dev/null +++ b/packages/store/src/cli/services/store/auth/list-result.ts @@ -0,0 +1,56 @@ +import {type StoreAuthListEntry, type StoreAuthListResult} from './list.js' +import {outputInfo, outputResult} from '@shopify/cli-kit/node/output' +import {renderTable} from '@shopify/cli-kit/node/ui' +import {formatShortDate} from '@shopify/cli-kit/common/string' +import {extractSubdomain} from '@shopify/cli-kit/common/url' + +export function writeStoreAuthListResult(result: StoreAuthListResult, format: 'text' | 'json'): void { + if (format === 'json') { + outputResult(JSON.stringify({sessions: result.sessions}, null, 2)) + return + } + + renderTextResult(result) +} + +function renderTextResult(result: StoreAuthListResult): void { + if (result.sessions.length === 0) { + outputInfo(emptyStateMessage()) + return + } + + outputInfo('Stores authenticated directly with `shopify store auth`:') + renderTable({ + rows: result.sessions.map((session) => ({ + store: extractSubdomain(session.store) ?? session.store, + account: accountLabel(session), + scopes: session.scopes.join(', '), + connected: formatShortDate(session.connectedAt), + })), + columns: { + store: {header: 'Store'}, + account: {header: 'Account'}, + scopes: {header: 'Scopes'}, + connected: {header: 'Connected'}, + }, + }) + outputInfo('To list stores in a Shopify organization, run `shopify store list`.') +} + +function emptyStateMessage(): string { + return [ + 'No stores are authenticated directly with `shopify store auth`.', + '', + 'Run `shopify store auth --store --scopes ` to authenticate a store.', + 'Run `shopify store list` to list stores in a Shopify organization.', + ].join('\n') +} + +function accountLabel(session: StoreAuthListEntry): string { + if (session.associatedUser?.email) return session.associatedUser.email + + const name = [session.associatedUser?.firstName, session.associatedUser?.lastName].filter(Boolean).join(' ') + if (name) return name + + return session.userId +} diff --git a/packages/store/src/cli/services/store/auth/list.test.ts b/packages/store/src/cli/services/store/auth/list.test.ts new file mode 100644 index 00000000000..7f61ebcc5e7 --- /dev/null +++ b/packages/store/src/cli/services/store/auth/list.test.ts @@ -0,0 +1,36 @@ +import {listStoreAuthSessions} from './list.js' +import {listStoredStoreAuthSummaries} from './stored-auth.js' +import {describe, expect, test, vi} from 'vitest' + +vi.mock('./stored-auth.js') + +describe('listStoreAuthSessions', () => { + test('projects stored store auth summaries into typed auth sessions', () => { + vi.mocked(listStoredStoreAuthSummaries).mockReturnValue([ + { + store: 'shop.myshopify.com', + userId: '42', + scopes: ['read_products'], + acquiredAt: '2026-03-27T00:00:00.000Z', + expiresAt: '2026-03-28T00:00:00.000Z', + refreshTokenExpiresAt: '2026-04-28T00:00:00.000Z', + associatedUser: {id: 42, email: 'merchant@example.com'}, + }, + ]) + + expect(listStoreAuthSessions()).toEqual({ + sessions: [ + { + kind: 'store', + store: 'shop.myshopify.com', + userId: '42', + scopes: ['read_products'], + connectedAt: '2026-03-27T00:00:00.000Z', + expiresAt: '2026-03-28T00:00:00.000Z', + refreshTokenExpiresAt: '2026-04-28T00:00:00.000Z', + associatedUser: {id: 42, email: 'merchant@example.com'}, + }, + ], + }) + }) +}) diff --git a/packages/store/src/cli/services/store/auth/list.ts b/packages/store/src/cli/services/store/auth/list.ts new file mode 100644 index 00000000000..1a28e07d981 --- /dev/null +++ b/packages/store/src/cli/services/store/auth/list.ts @@ -0,0 +1,31 @@ +import {listStoredStoreAuthSummaries, type StoredStoreAuthSummary} from './stored-auth.js' + +export interface StoreAuthListEntry { + kind: 'store' + store: string + userId: string + scopes: string[] + connectedAt: string + expiresAt?: string + refreshTokenExpiresAt?: string + associatedUser?: StoredStoreAuthSummary['associatedUser'] +} + +export interface StoreAuthListResult { + sessions: StoreAuthListEntry[] +} + +export function listStoreAuthSessions(): StoreAuthListResult { + return { + sessions: listStoredStoreAuthSummaries().map((summary) => ({ + kind: 'store', + store: summary.store, + userId: summary.userId, + scopes: summary.scopes, + connectedAt: summary.acquiredAt, + ...(summary.expiresAt ? {expiresAt: summary.expiresAt} : {}), + ...(summary.refreshTokenExpiresAt ? {refreshTokenExpiresAt: summary.refreshTokenExpiresAt} : {}), + ...(summary.associatedUser ? {associatedUser: summary.associatedUser} : {}), + })), + } +} diff --git a/packages/store/src/cli/services/store/list/result.test.ts b/packages/store/src/cli/services/store/list/result.test.ts index a1c654b97ce..83566d96559 100644 --- a/packages/store/src/cli/services/store/list/result.test.ts +++ b/packages/store/src/cli/services/store/list/result.test.ts @@ -38,6 +38,7 @@ describe('writeStoreListResult', () => { expect(output.info()).toContain('My Shop') expect(output.info()).toContain('Dev') expect(output.info()).toContain('May 22, 2026') + expect(output.info()).toContain('shopify auth list') }) test('renders the subdomain handle for non-myshopify hosts (local dev)', () => { @@ -78,6 +79,7 @@ describe('writeStoreListResult', () => { expect(output.warn()).toContain("Couldn't resolve a Shopify account for the current CLI session.") expect(output.info()).toContain('No stores were returned for the current CLI session.') + expect(output.info()).toContain('shopify auth list') }) test('renders the selected organization empty state', () => { @@ -94,6 +96,7 @@ describe('writeStoreListResult', () => { writeStoreListResult({source: 'organization', stores: []}, 'text') expect(output.info()).toContain('No stores found in your Shopify organization.') + expect(output.info()).toContain('shopify auth list') }) test('emits a {stores, organization} JSON document on stdout', () => { diff --git a/packages/store/src/cli/services/store/list/result.ts b/packages/store/src/cli/services/store/list/result.ts index 413590fa20d..b1a6b7b22e8 100644 --- a/packages/store/src/cli/services/store/list/result.ts +++ b/packages/store/src/cli/services/store/list/result.ts @@ -46,6 +46,7 @@ function renderTextResult(result: ListStoresResult): void { } renderOrganizationTable(result.stores) + outputInfo('To list stores authenticated directly with `shopify store auth`, run `shopify auth list`.') } function renderOrganizationTable(stores: StoreListEntry[]): void { @@ -67,14 +68,22 @@ function renderOrganizationTable(stores: StoreListEntry[]): void { function emptyStateMessage(result: ListStoresResult): string { if (result.notice) { - return 'No stores were returned for the current CLI session.' + return [ + 'No stores were returned for the current CLI session.', + '', + 'Run `shopify auth list` to list stores authenticated directly with `shopify store auth`.', + ].join('\n') } if (result.organization) { return `No stores found in ${result.organization.name}.` } - return 'No stores found in your Shopify organization.' + return [ + 'No stores found in your Shopify organization.', + '', + 'Run `shopify auth list` to list stores authenticated directly with `shopify store auth`.', + ].join('\n') } function subdomainFor(store: string): string { diff --git a/packages/store/src/index.ts b/packages/store/src/index.ts index eede458c992..4fa065d6cac 100644 --- a/packages/store/src/index.ts +++ b/packages/store/src/index.ts @@ -1,3 +1,4 @@ +import AuthList from './cli/commands/auth/list.js' import StoreAuth from './cli/commands/store/auth.js' import StoreCreateDev from './cli/commands/store/create/dev.js' import StoreCreatePreview from './cli/commands/store/create/preview.js' @@ -6,6 +7,7 @@ import StoreInfo from './cli/commands/store/info.js' import StoreList from './cli/commands/store/list.js' const COMMANDS = { + 'auth:list': AuthList, 'store:auth': StoreAuth, 'store:create:dev': StoreCreateDev, 'store:create:preview': StoreCreatePreview, From 0277146fde4b2023ca9a1ff8d47b25cece1d415d Mon Sep 17 00:00:00 2001 From: Donald Merand Date: Mon, 15 Jun 2026 10:40:08 -0400 Subject: [PATCH 2/3] Refresh generated docs data for auth list --- .../generated/generated_docs_data_v2.json | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs-shopify.dev/generated/generated_docs_data_v2.json b/docs-shopify.dev/generated/generated_docs_data_v2.json index b83f906791c..86e940ffa3d 100644 --- a/docs-shopify.dev/generated/generated_docs_data_v2.json +++ b/docs-shopify.dev/generated/generated_docs_data_v2.json @@ -2577,6 +2577,44 @@ "value": "export interface appwebhooktrigger {\n /**\n * The URL where the webhook payload should be sent.\n You will need a different address type for each delivery-method:\n · For remote HTTP testing, use a URL that starts with https://\n · For local HTTP testing, use http://localhost:{port}/{url-path}\n · For Google Pub/Sub, use pubsub://{project-id}:{topic-id}\n · For Amazon EventBridge, use an Amazon Resource Name (ARN) starting with arn:aws:events:\n * @environment SHOPIFY_FLAG_ADDRESS\n */\n '--address '?: string\n\n /**\n * The API Version of the webhook topic.\n * @environment SHOPIFY_FLAG_API_VERSION\n */\n '--api-version '?: string\n\n /**\n * The Client ID of your app.\n * @environment SHOPIFY_FLAG_CLIENT_ID\n */\n '--client-id '?: string\n\n /**\n * Your app's client secret. This secret allows us to return the X-Shopify-Hmac-SHA256 header that lets you validate the origin of the response that you receive.\n * @environment SHOPIFY_FLAG_CLIENT_SECRET\n */\n '--client-secret '?: string\n\n /**\n * The name of the app configuration.\n * @environment SHOPIFY_FLAG_APP_CONFIG\n */\n '-c, --config '?: string\n\n /**\n * Method chosen to deliver the topic payload. If not passed, it's inferred from the address.\n * @environment SHOPIFY_FLAG_DELIVERY_METHOD\n */\n '--delivery-method '?: string\n\n /**\n * This help. When you run the trigger command the CLI will prompt you for any information that isn't passed using flags.\n * @environment SHOPIFY_FLAG_HELP\n */\n '--help'?: ''\n\n /**\n * The path to your app directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Reset all your settings.\n * @environment SHOPIFY_FLAG_RESET\n */\n '--reset'?: ''\n\n /**\n * The requested webhook topic.\n * @environment SHOPIFY_FLAG_TOPIC\n */\n '--topic '?: string\n}" } }, + "authlist": { + "docs-shopify.dev/commands/interfaces/auth-list.interface.ts": { + "filePath": "docs-shopify.dev/commands/interfaces/auth-list.interface.ts", + "name": "authlist", + "description": "The following flags are available for the `auth list` command:", + "isPublicDocs": true, + "members": [ + { + "filePath": "docs-shopify.dev/commands/interfaces/auth-list.interface.ts", + "syntaxKind": "PropertySignature", + "name": "--no-color", + "value": "''", + "description": "Disable color output.", + "isOptional": true, + "environmentValue": "SHOPIFY_FLAG_NO_COLOR" + }, + { + "filePath": "docs-shopify.dev/commands/interfaces/auth-list.interface.ts", + "syntaxKind": "PropertySignature", + "name": "--verbose", + "value": "''", + "description": "Increase the verbosity of the output.", + "isOptional": true, + "environmentValue": "SHOPIFY_FLAG_VERBOSE" + }, + { + "filePath": "docs-shopify.dev/commands/interfaces/auth-list.interface.ts", + "syntaxKind": "PropertySignature", + "name": "-j, --json", + "value": "''", + "description": "Output the result as JSON. Automatically disables color output.", + "isOptional": true, + "environmentValue": "SHOPIFY_FLAG_JSON" + } + ], + "value": "export interface authlist {\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}" + } + }, "authlogin": { "docs-shopify.dev/commands/interfaces/auth-login.interface.ts": { "filePath": "docs-shopify.dev/commands/interfaces/auth-login.interface.ts", From 849999db9dda5e210e3a5963924aa7e6df0ca768 Mon Sep 17 00:00:00 2001 From: Donald Merand Date: Mon, 15 Jun 2026 10:59:26 -0400 Subject: [PATCH 3/3] Cover auth list text fallbacks Assisted-By: devx/425e6a4b-6ec9-421c-8f98-ab1725d0b996 --- .../interfaces/auth-list.interface.ts | 24 ----- .../generated/generated_docs_data_v2.json | 38 ------- packages/cli/README.md | 28 ----- packages/cli/oclif.manifest.json | 101 +++++++++--------- .../commands/{ => store}/auth/list.test.ts | 23 ++-- .../src/cli/commands/{ => store}/auth/list.ts | 10 +- .../services/store/auth/list-result.test.ts | 58 +++++++--- .../cli/services/store/auth/list-result.ts | 46 ++++---- .../cli/services/store/list/result.test.ts | 6 +- .../src/cli/services/store/list/result.ts | 6 +- packages/store/src/index.ts | 4 +- 11 files changed, 141 insertions(+), 203 deletions(-) delete mode 100644 docs-shopify.dev/commands/interfaces/auth-list.interface.ts rename packages/store/src/cli/commands/{ => store}/auth/list.test.ts (50%) rename packages/store/src/cli/commands/{ => store}/auth/list.ts (75%) diff --git a/docs-shopify.dev/commands/interfaces/auth-list.interface.ts b/docs-shopify.dev/commands/interfaces/auth-list.interface.ts deleted file mode 100644 index efa3d34319d..00000000000 --- a/docs-shopify.dev/commands/interfaces/auth-list.interface.ts +++ /dev/null @@ -1,24 +0,0 @@ -// This is an autogenerated file. Don't edit this file manually. -/** - * The following flags are available for the `auth list` command: - * @publicDocs - */ -export interface authlist { - /** - * Output the result as JSON. Automatically disables color output. - * @environment SHOPIFY_FLAG_JSON - */ - '-j, --json'?: '' - - /** - * Disable color output. - * @environment SHOPIFY_FLAG_NO_COLOR - */ - '--no-color'?: '' - - /** - * Increase the verbosity of the output. - * @environment SHOPIFY_FLAG_VERBOSE - */ - '--verbose'?: '' -} diff --git a/docs-shopify.dev/generated/generated_docs_data_v2.json b/docs-shopify.dev/generated/generated_docs_data_v2.json index 86e940ffa3d..b83f906791c 100644 --- a/docs-shopify.dev/generated/generated_docs_data_v2.json +++ b/docs-shopify.dev/generated/generated_docs_data_v2.json @@ -2577,44 +2577,6 @@ "value": "export interface appwebhooktrigger {\n /**\n * The URL where the webhook payload should be sent.\n You will need a different address type for each delivery-method:\n · For remote HTTP testing, use a URL that starts with https://\n · For local HTTP testing, use http://localhost:{port}/{url-path}\n · For Google Pub/Sub, use pubsub://{project-id}:{topic-id}\n · For Amazon EventBridge, use an Amazon Resource Name (ARN) starting with arn:aws:events:\n * @environment SHOPIFY_FLAG_ADDRESS\n */\n '--address '?: string\n\n /**\n * The API Version of the webhook topic.\n * @environment SHOPIFY_FLAG_API_VERSION\n */\n '--api-version '?: string\n\n /**\n * The Client ID of your app.\n * @environment SHOPIFY_FLAG_CLIENT_ID\n */\n '--client-id '?: string\n\n /**\n * Your app's client secret. This secret allows us to return the X-Shopify-Hmac-SHA256 header that lets you validate the origin of the response that you receive.\n * @environment SHOPIFY_FLAG_CLIENT_SECRET\n */\n '--client-secret '?: string\n\n /**\n * The name of the app configuration.\n * @environment SHOPIFY_FLAG_APP_CONFIG\n */\n '-c, --config '?: string\n\n /**\n * Method chosen to deliver the topic payload. If not passed, it's inferred from the address.\n * @environment SHOPIFY_FLAG_DELIVERY_METHOD\n */\n '--delivery-method '?: string\n\n /**\n * This help. When you run the trigger command the CLI will prompt you for any information that isn't passed using flags.\n * @environment SHOPIFY_FLAG_HELP\n */\n '--help'?: ''\n\n /**\n * The path to your app directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path '?: string\n\n /**\n * Reset all your settings.\n * @environment SHOPIFY_FLAG_RESET\n */\n '--reset'?: ''\n\n /**\n * The requested webhook topic.\n * @environment SHOPIFY_FLAG_TOPIC\n */\n '--topic '?: string\n}" } }, - "authlist": { - "docs-shopify.dev/commands/interfaces/auth-list.interface.ts": { - "filePath": "docs-shopify.dev/commands/interfaces/auth-list.interface.ts", - "name": "authlist", - "description": "The following flags are available for the `auth list` command:", - "isPublicDocs": true, - "members": [ - { - "filePath": "docs-shopify.dev/commands/interfaces/auth-list.interface.ts", - "syntaxKind": "PropertySignature", - "name": "--no-color", - "value": "''", - "description": "Disable color output.", - "isOptional": true, - "environmentValue": "SHOPIFY_FLAG_NO_COLOR" - }, - { - "filePath": "docs-shopify.dev/commands/interfaces/auth-list.interface.ts", - "syntaxKind": "PropertySignature", - "name": "--verbose", - "value": "''", - "description": "Increase the verbosity of the output.", - "isOptional": true, - "environmentValue": "SHOPIFY_FLAG_VERBOSE" - }, - { - "filePath": "docs-shopify.dev/commands/interfaces/auth-list.interface.ts", - "syntaxKind": "PropertySignature", - "name": "-j, --json", - "value": "''", - "description": "Output the result as JSON. Automatically disables color output.", - "isOptional": true, - "environmentValue": "SHOPIFY_FLAG_JSON" - } - ], - "value": "export interface authlist {\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}" - } - }, "authlogin": { "docs-shopify.dev/commands/interfaces/auth-login.interface.ts": { "filePath": "docs-shopify.dev/commands/interfaces/auth-login.interface.ts", diff --git a/packages/cli/README.md b/packages/cli/README.md index 6ac7ea8e666..62a97253975 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -30,7 +30,6 @@ * [`shopify app release --version `](#shopify-app-release---version-version) * [`shopify app versions list`](#shopify-app-versions-list) * [`shopify app webhook trigger`](#shopify-app-webhook-trigger) -* [`shopify auth list`](#shopify-auth-list) * [`shopify auth login`](#shopify-auth-login) * [`shopify auth logout`](#shopify-auth-logout) * [`shopify commands`](#shopify-commands) @@ -1048,33 +1047,6 @@ DESCRIPTION - You can't use this method to validate your API webhook subscriptions. ``` -## `shopify auth list` - -List stores authenticated directly with store auth. - -``` -USAGE - $ shopify auth list [-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. - -DESCRIPTION - List stores authenticated directly with store auth. - - Lists stores authenticated directly on this machine with `shopify store auth`. - - Use this command to find stores that can be used with store-authenticated commands such as `shopify store execute`. - To list stores in a Shopify organization, run `shopify store list`. - -EXAMPLES - $ shopify auth list - - $ shopify auth list --json -``` - ## `shopify auth login` Logs you in to your Shopify account. diff --git a/packages/cli/oclif.manifest.json b/packages/cli/oclif.manifest.json index 4a91cbba8aa..c8654ed3cf6 100644 --- a/packages/cli/oclif.manifest.json +++ b/packages/cli/oclif.manifest.json @@ -3048,56 +3048,6 @@ "strict": true, "summary": "Trigger delivery of a sample webhook topic payload to a designated address." }, - "auth:list": { - "aliases": [ - ], - "args": { - }, - "customPluginName": "@shopify/store", - "description": "Lists stores authenticated directly on this machine with `shopify store auth`.\n\nUse this command to find stores that can be used with store-authenticated commands such as `shopify store execute`.\nTo list stores in a Shopify organization, run `shopify store list`.", - "descriptionWithMarkdown": "Lists stores authenticated directly on this machine with `shopify store auth`.\n\nUse this command to find stores that can be used with store-authenticated commands such as `shopify store execute`.\nTo list stores in a Shopify organization, run `shopify store list`.", - "enableJsonFlag": false, - "examples": [ - "<%= config.bin %> <%= command.id %>", - "<%= config.bin %> <%= command.id %> --json" - ], - "flags": { - "json": { - "allowNo": false, - "char": "j", - "description": "Output the result as JSON. Automatically disables color output.", - "env": "SHOPIFY_FLAG_JSON", - "hidden": false, - "name": "json", - "type": "boolean" - }, - "no-color": { - "allowNo": false, - "description": "Disable color output.", - "env": "SHOPIFY_FLAG_NO_COLOR", - "hidden": false, - "name": "no-color", - "type": "boolean" - }, - "verbose": { - "allowNo": false, - "description": "Increase the verbosity of the output.", - "env": "SHOPIFY_FLAG_VERBOSE", - "hidden": false, - "name": "verbose", - "type": "boolean" - } - }, - "hasDynamicHelp": false, - "hiddenAliases": [ - ], - "id": "auth:list", - "pluginAlias": "@shopify/cli", - "pluginName": "@shopify/cli", - "pluginType": "core", - "strict": true, - "summary": "List stores authenticated directly with store auth." - }, "auth:login": { "aliases": [ ], @@ -5798,6 +5748,57 @@ "strict": true, "summary": "Authenticate an app against a store for store commands." }, + "store:auth:list": { + "aliases": [ + ], + "args": { + }, + "customPluginName": "@shopify/store", + "description": "Lists stores authenticated directly on this machine with `shopify store auth`.\n\nUse this command to find stores that can be used with store-authenticated commands such as `shopify store execute`.\nTo list stores in a Shopify organization, run `shopify store list`.", + "descriptionWithMarkdown": "Lists stores authenticated directly on this machine with `shopify store auth`.\n\nUse this command to find stores that can be used with store-authenticated commands such as `shopify store execute`.\nTo list stores in a Shopify organization, run `shopify store list`.", + "enableJsonFlag": false, + "examples": [ + "<%= config.bin %> <%= command.id %>", + "<%= config.bin %> <%= command.id %> --json" + ], + "flags": { + "json": { + "allowNo": false, + "char": "j", + "description": "Output the result as JSON. Automatically disables color output.", + "env": "SHOPIFY_FLAG_JSON", + "hidden": false, + "name": "json", + "type": "boolean" + }, + "no-color": { + "allowNo": false, + "description": "Disable color output.", + "env": "SHOPIFY_FLAG_NO_COLOR", + "hidden": false, + "name": "no-color", + "type": "boolean" + }, + "verbose": { + "allowNo": false, + "description": "Increase the verbosity of the output.", + "env": "SHOPIFY_FLAG_VERBOSE", + "hidden": false, + "name": "verbose", + "type": "boolean" + } + }, + "hasDynamicHelp": false, + "hidden": true, + "hiddenAliases": [ + ], + "id": "store:auth:list", + "pluginAlias": "@shopify/cli", + "pluginName": "@shopify/cli", + "pluginType": "core", + "strict": true, + "summary": "List stores authenticated directly with store auth." + }, "store:create:dev": { "aliases": [ ], diff --git a/packages/store/src/cli/commands/auth/list.test.ts b/packages/store/src/cli/commands/store/auth/list.test.ts similarity index 50% rename from packages/store/src/cli/commands/auth/list.test.ts rename to packages/store/src/cli/commands/store/auth/list.test.ts index 5a997090a08..9a6885238e9 100644 --- a/packages/store/src/cli/commands/auth/list.test.ts +++ b/packages/store/src/cli/commands/store/auth/list.test.ts @@ -1,16 +1,16 @@ -import AuthList from './list.js' -import {listStoreAuthSessions} from '../../services/store/auth/list.js' -import {writeStoreAuthListResult} from '../../services/store/auth/list-result.js' +import StoreAuthList from './list.js' +import {listStoreAuthSessions} from '../../../services/store/auth/list.js' +import {writeStoreAuthListResult} from '../../../services/store/auth/list-result.js' import {describe, expect, test, vi} from 'vitest' -vi.mock('../../services/store/auth/list.js') -vi.mock('../../services/store/auth/list-result.js') +vi.mock('../../../services/store/auth/list.js') +vi.mock('../../../services/store/auth/list-result.js') -describe('auth list command', () => { +describe('store auth list command', () => { test('lists direct store-auth sessions and writes text output by default', async () => { vi.mocked(listStoreAuthSessions).mockReturnValue({sessions: []}) - await AuthList.run([]) + await StoreAuthList.run([]) expect(listStoreAuthSessions).toHaveBeenCalledWith() expect(writeStoreAuthListResult).toHaveBeenCalledWith({sessions: []}, 'text') @@ -19,14 +19,15 @@ describe('auth list command', () => { test('writes json output when requested', async () => { vi.mocked(listStoreAuthSessions).mockReturnValue({sessions: []}) - await AuthList.run(['--json']) + await StoreAuthList.run(['--json']) expect(writeStoreAuthListResult).toHaveBeenCalledWith({sessions: []}, 'json') }) test('does not expose organization or source-selection flags', () => { - expect(AuthList.flags.json).toBeDefined() - expect(AuthList.flags).not.toHaveProperty('organization-id') - expect(AuthList.flags).not.toHaveProperty('from') + expect(StoreAuthList.hidden).toBe(true) + expect(StoreAuthList.flags.json).toBeDefined() + expect(StoreAuthList.flags).not.toHaveProperty('organization-id') + expect(StoreAuthList.flags).not.toHaveProperty('from') }) }) diff --git a/packages/store/src/cli/commands/auth/list.ts b/packages/store/src/cli/commands/store/auth/list.ts similarity index 75% rename from packages/store/src/cli/commands/auth/list.ts rename to packages/store/src/cli/commands/store/auth/list.ts index beb42d71e28..271fe414046 100644 --- a/packages/store/src/cli/commands/auth/list.ts +++ b/packages/store/src/cli/commands/store/auth/list.ts @@ -1,9 +1,11 @@ -import {listStoreAuthSessions} from '../../services/store/auth/list.js' -import {writeStoreAuthListResult} from '../../services/store/auth/list-result.js' +import {listStoreAuthSessions} from '../../../services/store/auth/list.js' +import {writeStoreAuthListResult} from '../../../services/store/auth/list-result.js' import Command from '@shopify/cli-kit/node/base-command' import {globalFlags, jsonFlag} from '@shopify/cli-kit/node/cli' -export default class AuthList extends Command { +export default class StoreAuthList extends Command { + static hidden = true + static summary = 'List stores authenticated directly with store auth.' static descriptionWithMarkdown = `Lists stores authenticated directly on this machine with \`shopify store auth\`. @@ -21,7 +23,7 @@ To list stores in a Shopify organization, run \`shopify store list\`.` } async run(): Promise { - const {flags} = await this.parse(AuthList) + const {flags} = await this.parse(StoreAuthList) const result = listStoreAuthSessions() writeStoreAuthListResult(result, flags.json ? 'json' : 'text') diff --git a/packages/store/src/cli/services/store/auth/list-result.test.ts b/packages/store/src/cli/services/store/auth/list-result.test.ts index ec12e795909..1634551a9b3 100644 --- a/packages/store/src/cli/services/store/auth/list-result.test.ts +++ b/packages/store/src/cli/services/store/auth/list-result.test.ts @@ -7,7 +7,7 @@ describe('writeStoreAuthListResult', () => { mockAndCaptureOutput().clear() }) - test('renders direct store-auth sessions with subdomain, account, scopes, and connected date', () => { + test('renders direct store-auth sessions with subdomain and connected date', () => { const output = mockAndCaptureOutput() writeStoreAuthListResult( @@ -26,14 +26,14 @@ describe('writeStoreAuthListResult', () => { 'text', ) - expect(output.info()).toContain('Stores authenticated directly with `shopify store auth`') - expect(output.info()).toContain('Store') + expect(output.info()).toContain('Subdomain') + expect(output.info()).toContain('Connected') expect(output.info()).toContain('my-shop') expect(output.info()).not.toContain('my-shop.myshopify.com') - expect(output.info()).toContain('merchant@example.com') - expect(output.info()).toContain('read_products, write_products') expect(output.info()).toContain('May 22, 2026') - expect(output.info()).toContain('shopify store list') + expect(output.info()).not.toContain('merchant@example.com') + expect(output.info()).not.toContain('read_products, write_products') + expect(output.info()).not.toContain('shopify store list') }) test('renders an empty state with auth and organization-list guidance', () => { @@ -46,22 +46,48 @@ describe('writeStoreAuthListResult', () => { expect(output.info()).toContain('shopify store list') }) - test('writes a deterministic JSON document', () => { + test('writes a deterministic JSON document with only subdomain and connected date', () => { const output = mockAndCaptureOutput() - const result = { + + writeStoreAuthListResult( + { + sessions: [ + { + kind: 'store', + store: 'shop.myshopify.com', + userId: '42', + scopes: ['read_products'], + connectedAt: '2026-05-22T00:00:00Z', + associatedUser: {id: 42, email: 'merchant@example.com'}, + }, + ], + }, + 'json', + ) + + expect(JSON.parse(output.output())).toEqual({ sessions: [ { - kind: 'store' as const, - store: 'shop.myshopify.com', - userId: '42', - scopes: ['read_products'], - connectedAt: '2026-05-22T00:00:00Z', + subdomain: 'shop', + connected: 'May 22, 2026', }, ], - } + }) + }) + + test('includes empty-state guidance in JSON output when there are no sessions', () => { + const output = mockAndCaptureOutput() - writeStoreAuthListResult(result, 'json') + writeStoreAuthListResult({sessions: []}, 'json') - expect(JSON.parse(output.output())).toEqual(result) + expect(JSON.parse(output.output())).toEqual({ + sessions: [], + message: [ + 'No stores are authenticated directly with `shopify store auth`.', + '', + 'Run `shopify store auth --store --scopes ` to authenticate a store.', + 'Run `shopify store list` to list stores in a Shopify organization.', + ].join('\n'), + }) }) }) diff --git a/packages/store/src/cli/services/store/auth/list-result.ts b/packages/store/src/cli/services/store/auth/list-result.ts index b9d6673df29..e8cba213c5d 100644 --- a/packages/store/src/cli/services/store/auth/list-result.ts +++ b/packages/store/src/cli/services/store/auth/list-result.ts @@ -1,40 +1,47 @@ -import {type StoreAuthListEntry, type StoreAuthListResult} from './list.js' +import {type StoreAuthListResult} from './list.js' +import {extractSubdomain, formatShortDate} from '../display.js' import {outputInfo, outputResult} from '@shopify/cli-kit/node/output' import {renderTable} from '@shopify/cli-kit/node/ui' -import {formatShortDate} from '@shopify/cli-kit/common/string' -import {extractSubdomain} from '@shopify/cli-kit/common/url' export function writeStoreAuthListResult(result: StoreAuthListResult, format: 'text' | 'json'): void { if (format === 'json') { - outputResult(JSON.stringify({sessions: result.sessions}, null, 2)) + outputResult(JSON.stringify(toJsonResult(result), null, 2)) return } renderTextResult(result) } +function toJsonResult(result: StoreAuthListResult): { + sessions: ReturnType[] + message?: string +} { + return { + sessions: result.sessions.map(toDisplaySession), + ...(result.sessions.length === 0 ? {message: emptyStateMessage()} : {}), + } +} + function renderTextResult(result: StoreAuthListResult): void { if (result.sessions.length === 0) { outputInfo(emptyStateMessage()) return } - outputInfo('Stores authenticated directly with `shopify store auth`:') renderTable({ - rows: result.sessions.map((session) => ({ - store: extractSubdomain(session.store) ?? session.store, - account: accountLabel(session), - scopes: session.scopes.join(', '), - connected: formatShortDate(session.connectedAt), - })), + rows: result.sessions.map(toDisplaySession), columns: { - store: {header: 'Store'}, - account: {header: 'Account'}, - scopes: {header: 'Scopes'}, + subdomain: {header: 'Subdomain'}, connected: {header: 'Connected'}, }, }) - outputInfo('To list stores in a Shopify organization, run `shopify store list`.') +} + +function toDisplaySession(session: StoreAuthListResult['sessions'][number]): {subdomain: string; connected: string} { + return { + subdomain: extractSubdomain(session.store) ?? session.store, + connected: formatShortDate(session.connectedAt), + } } function emptyStateMessage(): string { @@ -45,12 +52,3 @@ function emptyStateMessage(): string { 'Run `shopify store list` to list stores in a Shopify organization.', ].join('\n') } - -function accountLabel(session: StoreAuthListEntry): string { - if (session.associatedUser?.email) return session.associatedUser.email - - const name = [session.associatedUser?.firstName, session.associatedUser?.lastName].filter(Boolean).join(' ') - if (name) return name - - return session.userId -} diff --git a/packages/store/src/cli/services/store/list/result.test.ts b/packages/store/src/cli/services/store/list/result.test.ts index 83566d96559..cd84e69811b 100644 --- a/packages/store/src/cli/services/store/list/result.test.ts +++ b/packages/store/src/cli/services/store/list/result.test.ts @@ -38,7 +38,7 @@ describe('writeStoreListResult', () => { expect(output.info()).toContain('My Shop') expect(output.info()).toContain('Dev') expect(output.info()).toContain('May 22, 2026') - expect(output.info()).toContain('shopify auth list') + expect(output.info()).toContain('shopify store auth list') }) test('renders the subdomain handle for non-myshopify hosts (local dev)', () => { @@ -79,7 +79,7 @@ describe('writeStoreListResult', () => { expect(output.warn()).toContain("Couldn't resolve a Shopify account for the current CLI session.") expect(output.info()).toContain('No stores were returned for the current CLI session.') - expect(output.info()).toContain('shopify auth list') + expect(output.info()).toContain('shopify store auth list') }) test('renders the selected organization empty state', () => { @@ -96,7 +96,7 @@ describe('writeStoreListResult', () => { writeStoreListResult({source: 'organization', stores: []}, 'text') expect(output.info()).toContain('No stores found in your Shopify organization.') - expect(output.info()).toContain('shopify auth list') + expect(output.info()).toContain('shopify store auth list') }) test('emits a {stores, organization} JSON document on stdout', () => { diff --git a/packages/store/src/cli/services/store/list/result.ts b/packages/store/src/cli/services/store/list/result.ts index b1a6b7b22e8..925dbba7fee 100644 --- a/packages/store/src/cli/services/store/list/result.ts +++ b/packages/store/src/cli/services/store/list/result.ts @@ -46,7 +46,7 @@ function renderTextResult(result: ListStoresResult): void { } renderOrganizationTable(result.stores) - outputInfo('To list stores authenticated directly with `shopify store auth`, run `shopify auth list`.') + outputInfo('To list stores authenticated directly with `shopify store auth`, run `shopify store auth list`.') } function renderOrganizationTable(stores: StoreListEntry[]): void { @@ -71,7 +71,7 @@ function emptyStateMessage(result: ListStoresResult): string { return [ 'No stores were returned for the current CLI session.', '', - 'Run `shopify auth list` to list stores authenticated directly with `shopify store auth`.', + 'Run `shopify store auth list` to list stores authenticated directly with `shopify store auth`.', ].join('\n') } @@ -82,7 +82,7 @@ function emptyStateMessage(result: ListStoresResult): string { return [ 'No stores found in your Shopify organization.', '', - 'Run `shopify auth list` to list stores authenticated directly with `shopify store auth`.', + 'Run `shopify store auth list` to list stores authenticated directly with `shopify store auth`.', ].join('\n') } diff --git a/packages/store/src/index.ts b/packages/store/src/index.ts index 4fa065d6cac..89caa4a6946 100644 --- a/packages/store/src/index.ts +++ b/packages/store/src/index.ts @@ -1,4 +1,4 @@ -import AuthList from './cli/commands/auth/list.js' +import StoreAuthList from './cli/commands/store/auth/list.js' import StoreAuth from './cli/commands/store/auth.js' import StoreCreateDev from './cli/commands/store/create/dev.js' import StoreCreatePreview from './cli/commands/store/create/preview.js' @@ -7,7 +7,7 @@ import StoreInfo from './cli/commands/store/info.js' import StoreList from './cli/commands/store/list.js' const COMMANDS = { - 'auth:list': AuthList, + 'store:auth:list': StoreAuthList, 'store:auth': StoreAuth, 'store:create:dev': StoreCreateDev, 'store:create:preview': StoreCreatePreview,