Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// This is an autogenerated file. Don't edit this file manually.
export interface storeauthlogout {
/**
* Output the result as JSON. Automatically disables color output.
* @environment SHOPIFY_FLAG_JSON
*/
'-j, --json'?: ''

/**
* Disable color output.
* @environment SHOPIFY_FLAG_NO_COLOR
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// This is an autogenerated file. Don't edit this file manually.
export interface storeauth {
/**
* Output the result as JSON. Automatically disables color output.
* @environment SHOPIFY_FLAG_JSON
*/
'-j, --json'?: ''

/**
* Disable color output.
* @environment SHOPIFY_FLAG_NO_COLOR
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ export interface storeexecute {
*/
'--allow-mutations'?: ''

/**
* Output the result as JSON. Automatically disables color output.
* @environment SHOPIFY_FLAG_JSON
*/
'-j, --json'?: ''

/**
* Disable color output.
* @environment SHOPIFY_FLAG_NO_COLOR
Expand Down
15 changes: 12 additions & 3 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2059,9 +2059,10 @@ Authenticate an app against a store for store commands.

```
USAGE
$ shopify store auth --scopes <value> -s <value> [--no-color] [--verbose]
$ shopify store auth --scopes <value> -s <value> [-j] [--no-color] [--verbose]

FLAGS
-j, --json [env: SHOPIFY_FLAG_JSON] Output the result as JSON. Automatically disables color output.
-s, --store=<value> (required) [env: SHOPIFY_FLAG_STORE] The myshopify.com domain of the store to authenticate
against.
--no-color [env: SHOPIFY_FLAG_NO_COLOR] Disable color output.
Expand All @@ -2084,6 +2085,8 @@ DESCRIPTION

EXAMPLES
$ shopify store auth --store shop.myshopify.com --scopes read_products,write_products

$ shopify store auth --store shop.myshopify.com --scopes read_products,write_products --json
```

## `shopify store auth info`
Expand Down Expand Up @@ -2118,9 +2121,10 @@ Clear locally stored store auth for a store.

```
USAGE
$ shopify store auth logout -s <value> [--no-color] [--verbose]
$ shopify store auth logout -s <value> [-j] [--no-color] [--verbose]

FLAGS
-j, --json [env: SHOPIFY_FLAG_JSON] Output the result as JSON. Automatically disables color output.
-s, --store=<value> (required) [env: SHOPIFY_FLAG_STORE] The myshopify.com domain of the store to clear local auth
for.
--no-color [env: SHOPIFY_FLAG_NO_COLOR] Disable color output.
Expand All @@ -2135,6 +2139,8 @@ DESCRIPTION

EXAMPLES
$ shopify store auth logout --store shop.myshopify.com

$ shopify store auth logout --store shop.myshopify.com --json
```

## `shopify store execute`
Expand All @@ -2143,10 +2149,11 @@ Execute GraphQL queries and mutations on a store.

```
USAGE
$ shopify store execute -s <value> [--allow-mutations] [--no-color] [--output-file <value>] [-q <value>]
$ shopify store execute -s <value> [--allow-mutations] [-j] [--no-color] [--output-file <value>] [-q <value>]
[--query-file <value>] [--variable-file <value> | -v <value>] [--verbose] [--version <value>]

FLAGS
-j, --json [env: SHOPIFY_FLAG_JSON] Output the result as JSON. Automatically disables color output.
-q, --query=<value> [env: SHOPIFY_FLAG_QUERY] The GraphQL query or mutation, as a string.
-s, --store=<value> (required) [env: SHOPIFY_FLAG_STORE] The myshopify.com domain of the store to execute
against.
Expand Down Expand Up @@ -2180,6 +2187,8 @@ EXAMPLES
$ shopify store execute --store shop.myshopify.com --query-file ./operation.graphql --variables '{"id":"gid://shopify/Product/1"}'

$ shopify store execute --store shop.myshopify.com --query "mutation { shop { id } }" --allow-mutations

$ shopify store execute --store shop.myshopify.com --query "query { shop { name } }" --json
```

## `shopify theme check`
Expand Down
36 changes: 33 additions & 3 deletions packages/cli/oclif.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5743,9 +5743,19 @@
"descriptionWithMarkdown": "Authenticates the app against the specified store for store commands and stores an online access token for later reuse.\n\nRe-run this command if the stored token is missing, expires, or no longer has the scopes you need.\n\nTo inspect the locally stored auth state for a store, run [`shopify store auth info`](https://shopify.dev/docs/api/shopify-cli/store/store-auth-info).\n\nTo clear the locally stored auth state for a store, run [`shopify store auth logout`](https://shopify.dev/docs/api/shopify-cli/store/store-auth-logout).",
"enableJsonFlag": false,
"examples": [
"<%= config.bin %> <%= command.id %> --store shop.myshopify.com --scopes read_products,write_products"
"<%= config.bin %> <%= command.id %> --store shop.myshopify.com --scopes read_products,write_products",
"<%= config.bin %> <%= command.id %> --store shop.myshopify.com --scopes read_products,write_products --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.",
Expand Down Expand Up @@ -5860,9 +5870,19 @@
"descriptionWithMarkdown": "Clears the locally stored store auth for the specified store on this machine.\n\nThis does not revoke the app or remove granted scopes on Shopify.",
"enableJsonFlag": false,
"examples": [
"<%= config.bin %> <%= command.id %> --store shop.myshopify.com"
"<%= config.bin %> <%= command.id %> --store shop.myshopify.com",
"<%= config.bin %> <%= command.id %> --store shop.myshopify.com --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.",
Expand Down Expand Up @@ -5911,7 +5931,8 @@
"examples": [
"<%= config.bin %> <%= command.id %> --store shop.myshopify.com --query \"query { shop { name } }\"",
"<%= config.bin %> <%= command.id %> --store shop.myshopify.com --query-file ./operation.graphql --variables '{\"id\":\"gid://shopify/Product/1\"}'",
"<%= config.bin %> <%= command.id %> --store shop.myshopify.com --query \"mutation { shop { id } }\" --allow-mutations"
"<%= config.bin %> <%= command.id %> --store shop.myshopify.com --query \"mutation { shop { id } }\" --allow-mutations",
"<%= config.bin %> <%= command.id %> --store shop.myshopify.com --query \"query { shop { name } }\" --json"
],
"flags": {
"allow-mutations": {
Expand All @@ -5921,6 +5942,15 @@
"name": "allow-mutations",
"type": "boolean"
},
"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.",
Expand Down
29 changes: 23 additions & 6 deletions packages/cli/src/cli/commands/store/auth/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,43 @@
import {describe, test, expect, vi, beforeEach} from 'vitest'
import StoreAuth from './index.js'
import {authenticateStoreWithApp} from '../../../services/store/auth.js'
import {authenticateStoreWithApp, createStoreAuthPresenter} from '../../../services/store/auth.js'

vi.mock('../../../services/store/auth.js')
vi.mock('../../../services/store/auth.js', () => ({
authenticateStoreWithApp: vi.fn(),
createStoreAuthPresenter: vi.fn().mockReturnValue('presenter'),
}))

describe('store auth command', () => {
beforeEach(() => {
vi.clearAllMocks()
vi.mocked(createStoreAuthPresenter).mockReturnValue('presenter' as any)
})

test('passes parsed flags through to the auth service', async () => {
await StoreAuth.run(['--store', 'shop.myshopify.com', '--scopes', 'read_products,write_products'])

expect(authenticateStoreWithApp).toHaveBeenCalledWith({
store: 'shop.myshopify.com',
scopes: 'read_products,write_products',
})
expect(authenticateStoreWithApp).toHaveBeenCalledWith(
{
store: 'shop.myshopify.com',
scopes: 'read_products,write_products',
},
{
presenter: 'presenter',
},
)
expect(createStoreAuthPresenter).toHaveBeenCalledWith('text')
})

test('supports json output', async () => {
await StoreAuth.run(['--store', 'shop.myshopify.com', '--scopes', 'read_products,write_products', '--json'])

expect(createStoreAuthPresenter).toHaveBeenCalledWith('json')
})

test('defines the expected flags', () => {
expect(StoreAuth.flags.store).toBeDefined()
expect(StoreAuth.flags.scopes).toBeDefined()
expect(StoreAuth.flags.json).toBeDefined()
expect('port' in StoreAuth.flags).toBe(false)
expect('client-secret-file' in StoreAuth.flags).toBe(false)
})
Expand Down
23 changes: 16 additions & 7 deletions packages/cli/src/cli/commands/store/auth/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Command from '@shopify/cli-kit/node/base-command'
import {globalFlags} from '@shopify/cli-kit/node/cli'
import {globalFlags, jsonFlag} from '@shopify/cli-kit/node/cli'
import {normalizeStoreFqdn} from '@shopify/cli-kit/node/context/fqdn'
import {Flags} from '@oclif/core'
import {authenticateStoreWithApp} from '../../../services/store/auth.js'
import {authenticateStoreWithApp, createStoreAuthPresenter} from '../../../services/store/auth.js'

export default class StoreAuth extends Command {
static summary = 'Authenticate an app against a store for store commands.'
Expand All @@ -17,10 +17,14 @@ To clear the locally stored auth state for a store, run [\`shopify store auth lo

static description = this.descriptionWithoutMarkdown()

static examples = ['<%= config.bin %> <%= command.id %> --store shop.myshopify.com --scopes read_products,write_products']
static examples = [
'<%= config.bin %> <%= command.id %> --store shop.myshopify.com --scopes read_products,write_products',
'<%= config.bin %> <%= command.id %> --store shop.myshopify.com --scopes read_products,write_products --json',
]

static flags = {
...globalFlags,
...jsonFlag,
store: Flags.string({
char: 's',
description: 'The myshopify.com domain of the store to authenticate against.',
Expand All @@ -38,9 +42,14 @@ To clear the locally stored auth state for a store, run [\`shopify store auth lo
async run(): Promise<void> {
const {flags} = await this.parse(StoreAuth)

await authenticateStoreWithApp({
store: flags.store,
scopes: flags.scopes,
})
await authenticateStoreWithApp(
{
store: flags.store,
scopes: flags.scopes,
},
{
presenter: createStoreAuthPresenter(flags.json ? 'json' : 'text'),
},
)
}
}
9 changes: 8 additions & 1 deletion packages/cli/src/cli/commands/store/auth/logout.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('store auth logout command', () => {
await StoreAuthLogout.run(['--store', 'shop.myshopify.com'])

expect(logoutStoreAuth).toHaveBeenCalledWith('shop.myshopify.com')
expect(displayStoreAuthLogout).toHaveBeenCalledWith({store: 'shop.myshopify.com', cleared: true})
expect(displayStoreAuthLogout).toHaveBeenCalledWith({store: 'shop.myshopify.com', cleared: true}, 'text')
})

test('normalizes the store flag before calling the auth logout service', async () => {
Expand All @@ -26,7 +26,14 @@ describe('store auth logout command', () => {
expect(logoutStoreAuth).toHaveBeenCalledWith('shop.myshopify.com')
})

test('supports json output', async () => {
await StoreAuthLogout.run(['--store', 'shop.myshopify.com', '--json'])

expect(displayStoreAuthLogout).toHaveBeenCalledWith({store: 'shop.myshopify.com', cleared: true}, 'json')
})

test('defines the expected flags', () => {
expect(StoreAuthLogout.flags.store).toBeDefined()
expect(StoreAuthLogout.flags.json).toBeDefined()
})
})
10 changes: 7 additions & 3 deletions packages/cli/src/cli/commands/store/auth/logout.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Command from '@shopify/cli-kit/node/base-command'
import {globalFlags} from '@shopify/cli-kit/node/cli'
import {globalFlags, jsonFlag} from '@shopify/cli-kit/node/cli'
import {normalizeStoreFqdn} from '@shopify/cli-kit/node/context/fqdn'
import {Flags} from '@oclif/core'
import {displayStoreAuthLogout, logoutStoreAuth} from '../../../services/store/auth-logout.js'
Expand All @@ -13,10 +13,14 @@ This does not revoke the app or remove granted scopes on Shopify.`

static description = this.descriptionWithoutMarkdown()

static examples = ['<%= config.bin %> <%= command.id %> --store shop.myshopify.com']
static examples = [
'<%= config.bin %> <%= command.id %> --store shop.myshopify.com',
'<%= config.bin %> <%= command.id %> --store shop.myshopify.com --json',
]

static flags = {
...globalFlags,
...jsonFlag,
store: Flags.string({
char: 's',
description: 'The myshopify.com domain of the store to clear local auth for.',
Expand All @@ -30,6 +34,6 @@ This does not revoke the app or remove granted scopes on Shopify.`
const {flags} = await this.parse(StoreAuthLogout)

const result = logoutStoreAuth(flags.store)
displayStoreAuthLogout(result)
displayStoreAuthLogout(result, flags.json ? 'json' : 'text')
}
}
33 changes: 31 additions & 2 deletions packages/cli/src/cli/commands/store/execute.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import {describe, test, expect, vi, beforeEach} from 'vitest'
import StoreExecute from './execute.js'
import {writeOrOutputStoreExecuteResult} from '../../services/store/execute-result.js'
import {executeStoreOperation} from '../../services/store/execute.js'

vi.mock('../../services/store/execute.js')
vi.mock('../../services/store/execute-result.js', () => ({
writeOrOutputStoreExecuteResult: vi.fn(),
}))
vi.mock('../../services/store/execute.js', () => ({
executeStoreOperation: vi.fn().mockResolvedValue({data: {shop: {name: 'Test shop'}}}),
}))

describe('store execute command', () => {
beforeEach(() => {
vi.clearAllMocks()
vi.mocked(executeStoreOperation).mockResolvedValue({data: {shop: {name: 'Test shop'}}})
})

test('passes the inline query through to the service', async () => {
Expand All @@ -18,10 +25,21 @@ describe('store execute command', () => {
queryFile: undefined,
variables: undefined,
variableFile: undefined,
outputFile: undefined,
version: undefined,
allowMutations: false,
})
expect(writeOrOutputStoreExecuteResult).toHaveBeenCalledWith({data: {shop: {name: 'Test shop'}}}, undefined, 'text')
})

test('supports json output', async () => {
await StoreExecute.run(['--store', 'shop.myshopify.com', '--query', 'query { shop { name } }', '--json'])

expect(executeStoreOperation).toHaveBeenCalledWith(
expect.objectContaining({
store: 'shop.myshopify.com',
}),
)
expect(writeOrOutputStoreExecuteResult).toHaveBeenCalledWith({data: {shop: {name: 'Test shop'}}}, undefined, 'json')
})

test('passes the query file through to the service', async () => {
Expand All @@ -36,12 +54,23 @@ describe('store execute command', () => {
)
})

test('passes the output file through to the output writer', async () => {
await StoreExecute.run(['--store', 'shop.myshopify.com', '--query', 'query { shop { name } }', '--output-file', './result.json'])

expect(writeOrOutputStoreExecuteResult).toHaveBeenCalledWith(
{data: {shop: {name: 'Test shop'}}},
expect.stringMatching(/result\.json$/),
'text',
)
})

test('defines the expected flags', () => {
expect(StoreExecute.flags.store).toBeDefined()
expect(StoreExecute.flags.query).toBeDefined()
expect(StoreExecute.flags['query-file']).toBeDefined()
expect(StoreExecute.flags.variables).toBeDefined()
expect(StoreExecute.flags['variable-file']).toBeDefined()
expect(StoreExecute.flags['allow-mutations']).toBeDefined()
expect(StoreExecute.flags.json).toBeDefined()
})
})
Loading
Loading