Skip to content

Commit d7e721b

Browse files
actually run bulk ops
1 parent 0f5afcf commit d7e721b

File tree

2 files changed

+82
-2
lines changed

2 files changed

+82
-2
lines changed

packages/store/src/cli/commands/store/execute.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {readFile} from '@shopify/cli-kit/node/fs'
44
import {ensureAuthenticatedAdmin} from '@shopify/cli-kit/node/session'
55
import {adminRequest} from '@shopify/cli-kit/node/api/admin'
66
import {parseGraphQLOperation} from '../../services/graphql-parser.js'
7+
import {runBulkQuery} from '../../services/bulk-operations.js'
78

89
export default class Execute extends Command {
910
static summary = 'execute a graphql query or mutation on a store'
@@ -89,8 +90,15 @@ export default class Execute extends Command {
8990

9091
if (flags['bulk-operation']) {
9192
const operationType = parseGraphQLOperation(query)
92-
this.log(`executing bulk ${operationType}...`)
93-
this.error('bulk operations not yet implemented')
93+
94+
if (operationType === 'query') {
95+
this.log('starting bulk query...')
96+
const results = await runBulkQuery(query, adminSession)
97+
this.log(results)
98+
} else {
99+
this.error('bulk mutations not yet implemented')
100+
}
101+
return
94102
}
95103

96104
const result = await adminRequest(query, adminSession, variables)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import {AdminSession} from '@shopify/cli-kit/node/session'
2+
import {adminRequest} from '@shopify/cli-kit/node/api/admin'
3+
import {sleep} from '@shopify/cli-kit/node/system'
4+
import {fetch} from '@shopify/cli-kit/node/http'
5+
6+
const BULK_QUERY_MUTATION = `
7+
mutation bulkOperationRunQuery($query: String!) {
8+
bulkOperationRunQuery(query: $query) {
9+
bulkOperation {
10+
id
11+
status
12+
}
13+
userErrors {
14+
field
15+
message
16+
}
17+
}
18+
}
19+
`
20+
21+
const BULK_OPERATION_STATUS_QUERY = `
22+
query {
23+
currentBulkOperation {
24+
id
25+
status
26+
errorCode
27+
objectCount
28+
url
29+
}
30+
}
31+
`
32+
33+
interface BulkOperationStatus {
34+
currentBulkOperation: {
35+
id: string
36+
status: 'CREATED' | 'RUNNING' | 'COMPLETED' | 'FAILED' | 'CANCELED'
37+
errorCode?: string
38+
objectCount: string
39+
url?: string
40+
}
41+
}
42+
43+
export async function runBulkQuery(
44+
query: string,
45+
session: AdminSession,
46+
): Promise<string> {
47+
const startResult = await adminRequest<any>(BULK_QUERY_MUTATION, session, {query})
48+
49+
if (startResult.bulkOperationRunQuery.userErrors.length > 0) {
50+
const errors = startResult.bulkOperationRunQuery.userErrors.map((e: any) => e.message).join(', ')
51+
throw new Error(`bulk operation failed: ${errors}`)
52+
}
53+
54+
while (true) {
55+
await sleep(1000)
56+
57+
const statusResult = await adminRequest<BulkOperationStatus>(BULK_OPERATION_STATUS_QUERY, session)
58+
const operation = statusResult.currentBulkOperation
59+
60+
if (operation.status === 'COMPLETED') {
61+
if (!operation.url) {
62+
throw new Error('bulk operation completed but no results url')
63+
}
64+
const response = await fetch(operation.url)
65+
return await response.text()
66+
}
67+
68+
if (operation.status === 'FAILED') {
69+
throw new Error(`bulk operation failed: ${operation.errorCode}`)
70+
}
71+
}
72+
}

0 commit comments

Comments
 (0)