Skip to content

Commit f492b21

Browse files
committed
initial implementation of 'app execute'
1 parent a59fc98 commit f492b21

File tree

10 files changed

+573
-2
lines changed

10 files changed

+573
-2
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// This is an autogenerated file. Don't edit this file manually.
2+
import {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'
3+
4+
const data: ReferenceEntityTemplateSchema = {
5+
name: 'app execute',
6+
description: `Executes a GraphQL query or mutation on the specified store, and writes the result to STDOUT or a file.`,
7+
overviewPreviewDescription: `Execute GraphQL queries and mutations.`,
8+
type: 'command',
9+
isVisualComponent: false,
10+
defaultExample: {
11+
codeblock: {
12+
tabs: [
13+
{
14+
title: 'app execute',
15+
code: './examples/app-execute.example.sh',
16+
language: 'bash',
17+
},
18+
],
19+
title: 'app execute',
20+
},
21+
},
22+
definitions: [
23+
{
24+
title: 'Flags',
25+
description: 'The following flags are available for the `app execute` command:',
26+
type: 'appexecute',
27+
},
28+
],
29+
category: 'app',
30+
related: [
31+
],
32+
}
33+
34+
export default data
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
shopify app execute [flags]
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// This is an autogenerated file. Don't edit this file manually.
2+
export interface appexecute {
3+
/**
4+
* The Client ID of your app.
5+
* @environment SHOPIFY_FLAG_CLIENT_ID
6+
*/
7+
'--client-id <value>'?: string
8+
9+
/**
10+
* The name of the app configuration.
11+
* @environment SHOPIFY_FLAG_APP_CONFIG
12+
*/
13+
'-c, --config <value>'?: string
14+
15+
/**
16+
* Disable color output.
17+
* @environment SHOPIFY_FLAG_NO_COLOR
18+
*/
19+
'--no-color'?: ''
20+
21+
/**
22+
* The file name where results should be written, instead of STDOUT.
23+
* @environment SHOPIFY_FLAG_OUTPUT_FILE
24+
*/
25+
'--output-file <value>'?: string
26+
27+
/**
28+
* The path to your app directory.
29+
* @environment SHOPIFY_FLAG_PATH
30+
*/
31+
'--path <value>'?: string
32+
33+
/**
34+
* The GraphQL query or mutation, as a string.
35+
* @environment SHOPIFY_FLAG_QUERY
36+
*/
37+
'-q, --query <value>'?: string
38+
39+
/**
40+
* Reset all your settings.
41+
* @environment SHOPIFY_FLAG_RESET
42+
*/
43+
'--reset'?: ''
44+
45+
/**
46+
* The myshopify.com domain of the store to execute against. The app must be installed on the store. If not specified, you will be prompted to select a store.
47+
* @environment SHOPIFY_FLAG_STORE
48+
*/
49+
'-s, --store <value>'?: string
50+
51+
/**
52+
* The values for any GraphQL variables in your query or mutation, in JSON format.
53+
* @environment SHOPIFY_FLAG_VARIABLES
54+
*/
55+
'-v, --variables <value>'?: string
56+
57+
/**
58+
* Increase the verbosity of the output.
59+
* @environment SHOPIFY_FLAG_VERBOSE
60+
*/
61+
'--verbose'?: ''
62+
63+
/**
64+
* The API version to use for the query or mutation. Defaults to the latest stable version.
65+
* @environment SHOPIFY_FLAG_VERSION
66+
*/
67+
'--version <value>'?: string
68+
}

docs-shopify.dev/generated/generated_docs_data.json

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,143 @@
998998
"category": "app",
999999
"related": []
10001000
},
1001+
{
1002+
"name": "app execute",
1003+
"description": "Executes a GraphQL query or mutation on the specified store, and writes the result to STDOUT or a file.",
1004+
"overviewPreviewDescription": "Execute GraphQL queries and mutations.",
1005+
"type": "command",
1006+
"isVisualComponent": false,
1007+
"defaultExample": {
1008+
"codeblock": {
1009+
"tabs": [
1010+
{
1011+
"title": "app execute",
1012+
"code": "shopify app execute [flags]",
1013+
"language": "bash"
1014+
}
1015+
],
1016+
"title": "app execute"
1017+
}
1018+
},
1019+
"definitions": [
1020+
{
1021+
"title": "Flags",
1022+
"description": "The following flags are available for the `app execute` command:",
1023+
"type": "appexecute",
1024+
"typeDefinitions": {
1025+
"appexecute": {
1026+
"filePath": "docs-shopify.dev/commands/interfaces/app-execute.interface.ts",
1027+
"name": "appexecute",
1028+
"description": "",
1029+
"members": [
1030+
{
1031+
"filePath": "docs-shopify.dev/commands/interfaces/app-execute.interface.ts",
1032+
"syntaxKind": "PropertySignature",
1033+
"name": "--client-id <value>",
1034+
"value": "string",
1035+
"description": "The Client ID of your app.",
1036+
"isOptional": true,
1037+
"environmentValue": "SHOPIFY_FLAG_CLIENT_ID"
1038+
},
1039+
{
1040+
"filePath": "docs-shopify.dev/commands/interfaces/app-execute.interface.ts",
1041+
"syntaxKind": "PropertySignature",
1042+
"name": "--no-color",
1043+
"value": "\"\"",
1044+
"description": "Disable color output.",
1045+
"isOptional": true,
1046+
"environmentValue": "SHOPIFY_FLAG_NO_COLOR"
1047+
},
1048+
{
1049+
"filePath": "docs-shopify.dev/commands/interfaces/app-execute.interface.ts",
1050+
"syntaxKind": "PropertySignature",
1051+
"name": "--output-file <value>",
1052+
"value": "string",
1053+
"description": "The file name where results should be written, instead of STDOUT.",
1054+
"isOptional": true,
1055+
"environmentValue": "SHOPIFY_FLAG_OUTPUT_FILE"
1056+
},
1057+
{
1058+
"filePath": "docs-shopify.dev/commands/interfaces/app-execute.interface.ts",
1059+
"syntaxKind": "PropertySignature",
1060+
"name": "--path <value>",
1061+
"value": "string",
1062+
"description": "The path to your app directory.",
1063+
"isOptional": true,
1064+
"environmentValue": "SHOPIFY_FLAG_PATH"
1065+
},
1066+
{
1067+
"filePath": "docs-shopify.dev/commands/interfaces/app-execute.interface.ts",
1068+
"syntaxKind": "PropertySignature",
1069+
"name": "--reset",
1070+
"value": "\"\"",
1071+
"description": "Reset all your settings.",
1072+
"isOptional": true,
1073+
"environmentValue": "SHOPIFY_FLAG_RESET"
1074+
},
1075+
{
1076+
"filePath": "docs-shopify.dev/commands/interfaces/app-execute.interface.ts",
1077+
"syntaxKind": "PropertySignature",
1078+
"name": "--verbose",
1079+
"value": "\"\"",
1080+
"description": "Increase the verbosity of the output.",
1081+
"isOptional": true,
1082+
"environmentValue": "SHOPIFY_FLAG_VERBOSE"
1083+
},
1084+
{
1085+
"filePath": "docs-shopify.dev/commands/interfaces/app-execute.interface.ts",
1086+
"syntaxKind": "PropertySignature",
1087+
"name": "--version <value>",
1088+
"value": "string",
1089+
"description": "The API version to use for the query or mutation. Defaults to the latest stable version.",
1090+
"isOptional": true,
1091+
"environmentValue": "SHOPIFY_FLAG_VERSION"
1092+
},
1093+
{
1094+
"filePath": "docs-shopify.dev/commands/interfaces/app-execute.interface.ts",
1095+
"syntaxKind": "PropertySignature",
1096+
"name": "-c, --config <value>",
1097+
"value": "string",
1098+
"description": "The name of the app configuration.",
1099+
"isOptional": true,
1100+
"environmentValue": "SHOPIFY_FLAG_APP_CONFIG"
1101+
},
1102+
{
1103+
"filePath": "docs-shopify.dev/commands/interfaces/app-execute.interface.ts",
1104+
"syntaxKind": "PropertySignature",
1105+
"name": "-q, --query <value>",
1106+
"value": "string",
1107+
"description": "The GraphQL query or mutation, as a string.",
1108+
"isOptional": true,
1109+
"environmentValue": "SHOPIFY_FLAG_QUERY"
1110+
},
1111+
{
1112+
"filePath": "docs-shopify.dev/commands/interfaces/app-execute.interface.ts",
1113+
"syntaxKind": "PropertySignature",
1114+
"name": "-s, --store <value>",
1115+
"value": "string",
1116+
"description": "The myshopify.com domain of the store to execute against. The app must be installed on the store. If not specified, you will be prompted to select a store.",
1117+
"isOptional": true,
1118+
"environmentValue": "SHOPIFY_FLAG_STORE"
1119+
},
1120+
{
1121+
"filePath": "docs-shopify.dev/commands/interfaces/app-execute.interface.ts",
1122+
"syntaxKind": "PropertySignature",
1123+
"name": "-v, --variables <value>",
1124+
"value": "string",
1125+
"description": "The values for any GraphQL variables in your query or mutation, in JSON format.",
1126+
"isOptional": true,
1127+
"environmentValue": "SHOPIFY_FLAG_VARIABLES"
1128+
}
1129+
],
1130+
"value": "export interface appexecute {\n /**\n * The Client ID of your app.\n * @environment SHOPIFY_FLAG_CLIENT_ID\n */\n '--client-id <value>'?: string\n\n /**\n * The name of the app configuration.\n * @environment SHOPIFY_FLAG_APP_CONFIG\n */\n '-c, --config <value>'?: string\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 path to your app directory.\n * @environment SHOPIFY_FLAG_PATH\n */\n '--path <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 * Reset all your settings.\n * @environment SHOPIFY_FLAG_RESET\n */\n '--reset'?: ''\n\n /**\n * The myshopify.com domain of the store to execute against. The app must be installed on the store. If not specified, you will be prompted to select a store.\n * @environment SHOPIFY_FLAG_STORE\n */\n '-s, --store <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}"
1131+
}
1132+
}
1133+
}
1134+
],
1135+
"category": "app",
1136+
"related": []
1137+
},
10011138
{
10021139
"name": "app function build",
10031140
"description": "Compiles the function in your current directory to WebAssembly (Wasm) for testing purposes.",
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import {appFlags, operationFlags} from '../../flags.js'
2+
import AppLinkedCommand, {AppLinkedCommandOutput} from '../../utilities/app-linked-command.js'
3+
import {linkedAppContext} from '../../services/app-context.js'
4+
import {storeContext} from '../../services/store-context.js'
5+
import {executeOperation} from '../../services/execute-operation.js'
6+
import {globalFlags} from '@shopify/cli-kit/node/cli'
7+
import {readStdinString} from '@shopify/cli-kit/node/system'
8+
import {AbortError} from '@shopify/cli-kit/node/error'
9+
10+
export default class Execute extends AppLinkedCommand {
11+
static summary = 'Execute GraphQL queries and mutations.'
12+
13+
static description =
14+
'Executes a GraphQL query or mutation on the specified store, and writes the result to STDOUT or a file.'
15+
16+
static flags = {
17+
...globalFlags,
18+
...appFlags,
19+
...operationFlags,
20+
}
21+
22+
async run(): Promise<AppLinkedCommandOutput> {
23+
const {flags} = await this.parse(Execute)
24+
25+
const query = flags.query ?? (await readStdinString())
26+
if (!query) {
27+
throw new AbortError(
28+
'No query provided. Use the --query flag or pipe input via stdin.',
29+
'Example: echo "query { shop { name } }" | shopify app execute',
30+
)
31+
}
32+
33+
const appContextResult = await linkedAppContext({
34+
directory: flags.path,
35+
clientId: flags['client-id'],
36+
forceRelink: flags.reset,
37+
userProvidedConfigName: flags.config,
38+
})
39+
40+
const store = await storeContext({
41+
appContextResult,
42+
storeFqdn: flags.store,
43+
forceReselectStore: flags.reset,
44+
})
45+
46+
await executeOperation({
47+
remoteApp: appContextResult.remoteApp,
48+
storeFqdn: store.shopDomain,
49+
query,
50+
variables: flags.variables,
51+
apiVersion: flags.version,
52+
outputFile: flags['output-file'],
53+
})
54+
55+
return {app: appContextResult.app}
56+
}
57+
}

packages/app/src/cli/flags.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,32 @@ export const bulkOperationFlags = {
7373
env: 'SHOPIFY_FLAG_OUTPUT_FILE',
7474
}),
7575
}
76+
77+
export const operationFlags = {
78+
query: Flags.string({
79+
char: 'q',
80+
description: 'The GraphQL query or mutation, as a string.',
81+
env: 'SHOPIFY_FLAG_QUERY',
82+
required: false,
83+
}),
84+
variables: Flags.string({
85+
char: 'v',
86+
description: 'The values for any GraphQL variables in your query or mutation, in JSON format.',
87+
env: 'SHOPIFY_FLAG_VARIABLES',
88+
}),
89+
store: Flags.string({
90+
char: 's',
91+
description:
92+
'The myshopify.com domain of the store to execute against. The app must be installed on the store. If not specified, you will be prompted to select a store.',
93+
env: 'SHOPIFY_FLAG_STORE',
94+
parse: async (input) => normalizeStoreFqdn(input),
95+
}),
96+
version: Flags.string({
97+
description: 'The API version to use for the query or mutation. Defaults to the latest stable version.',
98+
env: 'SHOPIFY_FLAG_VERSION',
99+
}),
100+
'output-file': Flags.string({
101+
description: 'The file name where results should be written, instead of STDOUT.',
102+
env: 'SHOPIFY_FLAG_OUTPUT_FILE',
103+
}),
104+
}

packages/app/src/cli/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import Logs from './commands/app/logs.js'
1010
import Sources from './commands/app/app-logs/sources.js'
1111
import EnvPull from './commands/app/env/pull.js'
1212
import EnvShow from './commands/app/env/show.js'
13-
import Execute from './commands/app/bulk/execute.js'
13+
import BulkExecute from './commands/app/bulk/execute.js'
14+
import Execute from './commands/app/execute.js'
1415
import FunctionBuild from './commands/app/function/build.js'
1516
import FunctionReplay from './commands/app/function/replay.js'
1617
import FunctionRun from './commands/app/function/run.js'
@@ -53,7 +54,8 @@ export const commands: {[key: string]: typeof AppLinkedCommand | typeof AppUnlin
5354
'app:config:pull': ConfigPull,
5455
'app:env:pull': EnvPull,
5556
'app:env:show': EnvShow,
56-
'app:bulk:execute': Execute,
57+
'app:execute': Execute,
58+
'app:bulk:execute': BulkExecute,
5759
'app:generate:schema': GenerateSchema,
5860
'app:function:build': FunctionBuild,
5961
'app:function:replay': FunctionReplay,

0 commit comments

Comments
 (0)