Skip to content
Open
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 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
22 changes: 20 additions & 2 deletions docs-shopify.dev/generated/generated_docs_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -5829,6 +5829,15 @@
"isOptional": true,
"environmentValue": "SHOPIFY_FLAG_VERBOSE"
},
{
"filePath": "docs-shopify.dev/commands/interfaces/store-auth.interface.ts",
"syntaxKind": "PropertySignature",
"name": "-j, --json",
"value": "\"\"",
"description": "Output the result as JSON. Automatically disables color output.",
"isOptional": true,
"environmentValue": "SHOPIFY_FLAG_JSON"
},
{
"filePath": "docs-shopify.dev/commands/interfaces/store-auth.interface.ts",
"syntaxKind": "PropertySignature",
Expand All @@ -5838,7 +5847,7 @@
"environmentValue": "SHOPIFY_FLAG_STORE"
}
],
"value": "export interface storeauth {\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Comma-separated Admin API scopes to request for the app.\n * @environment SHOPIFY_FLAG_SCOPES\n */\n '--scopes <value>': string\n\n /**\n * The myshopify.com domain of the store to authenticate against.\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store <value>': string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}"
"value": "export interface storeauth {\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 * Comma-separated Admin API scopes to request for the app.\n * @environment SHOPIFY_FLAG_SCOPES\n */\n '--scopes <value>': string\n\n /**\n * The myshopify.com domain of the store to authenticate against.\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store <value>': string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}"
}
}
}
Expand Down Expand Up @@ -5938,6 +5947,15 @@
"isOptional": true,
"environmentValue": "SHOPIFY_FLAG_VERSION"
},
{
"filePath": "docs-shopify.dev/commands/interfaces/store-execute.interface.ts",
"syntaxKind": "PropertySignature",
"name": "-j, --json",
"value": "\"\"",
"description": "Output the result as JSON. Automatically disables color output.",
"isOptional": true,
"environmentValue": "SHOPIFY_FLAG_JSON"
},
{
"filePath": "docs-shopify.dev/commands/interfaces/store-execute.interface.ts",
"syntaxKind": "PropertySignature",
Expand Down Expand Up @@ -5965,7 +5983,7 @@
"environmentValue": "SHOPIFY_FLAG_VARIABLES"
}
],
"value": "export interface storeexecute {\n /**\n * Allow GraphQL mutations to run against the target store.\n * @environment SHOPIFY_FLAG_ALLOW_MUTATIONS\n */\n '--allow-mutations'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * The file name where results should be written, instead of STDOUT.\n * @environment SHOPIFY_FLAG_OUTPUT_FILE\n */\n '--output-file <value>'?: string\n\n /**\n * The GraphQL query or mutation, as a string.\n * @environment SHOPIFY_FLAG_QUERY\n */\n '-q, --query <value>'?: string\n\n /**\n * Path to a file containing the GraphQL query or mutation. Can't be used with --query.\n * @environment SHOPIFY_FLAG_QUERY_FILE\n */\n '--query-file <value>'?: string\n\n /**\n * The myshopify.com domain of the store to execute against.\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store <value>': string\n\n /**\n * Path to a file containing GraphQL variables in JSON format. Can't be used with --variables.\n * @environment SHOPIFY_FLAG_VARIABLE_FILE\n */\n '--variable-file <value>'?: string\n\n /**\n * The values for any GraphQL variables in your query or mutation, in JSON format.\n * @environment SHOPIFY_FLAG_VARIABLES\n */\n '-v, --variables <value>'?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n\n /**\n * The API version to use for the query or mutation. Defaults to the latest stable version.\n * @environment SHOPIFY_FLAG_VERSION\n */\n '--version <value>'?: string\n}"
"value": "export interface storeexecute {\n /**\n * Allow GraphQL mutations to run against the target store.\n * @environment SHOPIFY_FLAG_ALLOW_MUTATIONS\n */\n '--allow-mutations'?: ''\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 * The file name where results should be written, instead of STDOUT.\n * @environment SHOPIFY_FLAG_OUTPUT_FILE\n */\n '--output-file <value>'?: string\n\n /**\n * The GraphQL query or mutation, as a string.\n * @environment SHOPIFY_FLAG_QUERY\n */\n '-q, --query <value>'?: string\n\n /**\n * Path to a file containing the GraphQL query or mutation. Can't be used with --query.\n * @environment SHOPIFY_FLAG_QUERY_FILE\n */\n '--query-file <value>'?: string\n\n /**\n * The myshopify.com domain of the store to execute against.\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store <value>': string\n\n /**\n * Path to a file containing GraphQL variables in JSON format. Can't be used with --variables.\n * @environment SHOPIFY_FLAG_VARIABLE_FILE\n */\n '--variable-file <value>'?: string\n\n /**\n * The values for any GraphQL variables in your query or mutation, in JSON format.\n * @environment SHOPIFY_FLAG_VARIABLES\n */\n '-v, --variables <value>'?: string\n\n /**\n * Increase the verbosity of the output.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n\n /**\n * The API version to use for the query or mutation. Defaults to the latest stable version.\n * @environment SHOPIFY_FLAG_VERSION\n */\n '--version <value>'?: string\n}"
}
}
}
Expand Down
10 changes: 8 additions & 2 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2057,9 +2057,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 @@ -2076,6 +2077,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 execute`
Expand All @@ -2084,10 +2087,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 @@ -2121,6 +2125,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
24 changes: 22 additions & 2 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.",
"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 @@ -5803,7 +5813,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 @@ -5813,6 +5824,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
32 changes: 27 additions & 5 deletions packages/cli/src/cli/commands/store/auth.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import {describe, test, expect, vi, beforeEach} from 'vitest'
import {beforeEach, describe, expect, test, vi} from 'vitest'
import StoreAuth from './auth.js'
import {authenticateStoreWithApp} from '../../services/store/auth/index.js'
import {createStoreAuthPresenter} from '../../services/store/auth/result.js'

vi.mock('../../services/store/auth/index.js')
vi.mock('../../services/store/auth/result.js', () => ({
createStoreAuthPresenter: vi.fn((format: 'text' | 'json') => ({format})),
}))

describe('store auth command', () => {
beforeEach(() => {
Expand All @@ -12,15 +16,33 @@ describe('store auth command', () => {
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(createStoreAuthPresenter).toHaveBeenCalledWith('text')
expect(authenticateStoreWithApp).toHaveBeenCalledWith(
{
store: 'shop.myshopify.com',
scopes: 'read_products,write_products',
},
{presenter: {format: 'text'}},
)
})

test('passes a json presenter when --json is provided', async () => {
await StoreAuth.run(['--store', 'shop.myshopify.com', '--scopes', 'read_products', '--json'])

expect(createStoreAuthPresenter).toHaveBeenCalledWith('json')
expect(authenticateStoreWithApp).toHaveBeenCalledWith(
{
store: 'shop.myshopify.com',
scopes: 'read_products',
},
{presenter: {format: '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
22 changes: 16 additions & 6 deletions packages/cli/src/cli/commands/store/auth.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
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/index.js'
import {createStoreAuthPresenter} from '../../services/store/auth/result.js'

export default class StoreAuth extends Command {
static summary = 'Authenticate an app against a store for store commands.'
Expand All @@ -13,10 +14,14 @@ Re-run this command if the stored token is missing, expires, or no longer has th

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 @@ -34,9 +39,14 @@ Re-run this command if the stored token is missing, expires, or no longer has th
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'),
},
)
}
}
24 changes: 21 additions & 3 deletions packages/cli/src/cli/commands/store/execute.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import {describe, test, expect, vi, beforeEach} from 'vitest'
import {beforeEach, describe, expect, test, vi} from 'vitest'
import StoreExecute from './execute.js'
import {executeStoreOperation} from '../../services/store/execute/index.js'
import {writeOrOutputStoreExecuteResult} from '../../services/store/execute/result.js'

vi.mock('../../services/store/execute/index.js')
vi.mock('../../services/store/execute/result.js')

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 () => {
test('passes the inline query through to the service and writes the result', async () => {
await StoreExecute.run(['--store', 'shop.myshopify.com', '--query', 'query { shop { name } }'])

expect(executeStoreOperation).toHaveBeenCalledWith({
Expand All @@ -18,10 +21,14 @@ 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('passes the query file through to the service', async () => {
Expand All @@ -36,12 +43,23 @@ describe('store execute command', () => {
)
})

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

expect(writeOrOutputStoreExecuteResult).toHaveBeenCalledWith(
{data: {shop: {name: 'Test shop'}}},
undefined,
'json',
)
})

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()
})
})
10 changes: 7 additions & 3 deletions packages/cli/src/cli/commands/store/execute.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
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 {resolvePath} from '@shopify/cli-kit/node/path'
import {Flags} from '@oclif/core'
import {executeStoreOperation} from '../../services/store/execute/index.js'
import {writeOrOutputStoreExecuteResult} from '../../services/store/execute/result.js'

export default class StoreExecute extends Command {
static summary = 'Execute GraphQL queries and mutations on a store.'
Expand All @@ -20,10 +21,12 @@ Mutations are disabled by default. Re-run with \`--allow-mutations\` if you inte
'<%= 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 "query { shop { name } }" --json',
]

static flags = {
...globalFlags,
...jsonFlag,
query: Flags.string({
char: 'q',
description: 'The GraphQL query or mutation, as a string.',
Expand Down Expand Up @@ -75,15 +78,16 @@ Mutations are disabled by default. Re-run with \`--allow-mutations\` if you inte
async run(): Promise<void> {
const {flags} = await this.parse(StoreExecute)

await executeStoreOperation({
const result = await executeStoreOperation({
store: flags.store,
query: flags.query,
queryFile: flags['query-file'],
variables: flags.variables,
variableFile: flags['variable-file'],
outputFile: flags['output-file'],
version: flags.version,
allowMutations: flags['allow-mutations'],
})

await writeOrOutputStoreExecuteResult(result, flags['output-file'], flags.json ? 'json' : 'text')
}
}
Loading
Loading