Skip to content

Commit 1a8018f

Browse files
nickwesselmanericlee878
authored andcommitted
lint fix
1 parent 7f004d4 commit 1a8018f

File tree

7 files changed

+107
-58
lines changed

7 files changed

+107
-58
lines changed

packages/app/src/cli/api/graphql/app-dev/generated/types.d.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, tsdoc/syntax */
1+
/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax */
22
import {JsonMapType} from '@shopify/cli-kit/node/toml'
33

44
export type Maybe<T> = T | null
@@ -15,6 +15,12 @@ export type Scalars = {
1515
Boolean: {input: boolean; output: boolean}
1616
Int: {input: number; output: number}
1717
Float: {input: number; output: number}
18+
/**
19+
* Represents an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-encoded date and time string.
20+
* For example, 3:50 pm on September 7, 2019 in the time zone of UTC (Coordinated Universal Time) is
21+
* represented as `"2019-09-07T15:50:00Z`".
22+
*/
23+
DateTime: {input: any; output: any}
1824
/**
1925
* A [JSON](https://www.json.org/json-en.html) object.
2026
*
@@ -31,4 +37,12 @@ export type Scalars = {
3137
* }`
3238
*/
3339
JSON: {input: JsonMapType | string; output: JsonMapType}
40+
/**
41+
* Represents an [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) and
42+
* [RFC 3987](https://datatracker.ietf.org/doc/html/rfc3987)-compliant URI string.
43+
*
44+
* For example, `"https://example.myshopify.com"` is a valid URL. It includes a scheme (`https`) and a host
45+
* (`example.myshopify.com`).
46+
*/
47+
URL: {input: string; output: string}
3448
}

packages/app/src/cli/api/graphql/bulk-operations/generated/types.d.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,6 @@ export type BulkOperationsSortKeys =
210210
| 'COMPLETED_AT'
211211
/** Sort by the `created_at` value. */
212212
| 'CREATED_AT'
213-
/** Sort by the `status` value. */
214-
| 'STATUS'
215213

216214
/**
217215
* The possible HTTP methods that can be used when sending a request to upload a file using information from a
Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
query FetchDevStoreByDomain($domain: String) {
2-
organization {
3-
id
4-
name
5-
accessibleShops(filters: {field: STORE_TYPE, operator: EQUALS, value: "app_development"}, search: $domain) {
6-
edges {
7-
node {
8-
id
9-
externalId
10-
name
11-
storeType
12-
primaryDomain
13-
shortName
14-
url
15-
}
1+
query FetchDevStoreByDomain($domain: String) {
2+
organization {
3+
id
4+
name
5+
accessibleShops(filters: {field: STORE_TYPE, operator: EQUALS, value: "app_development"}, search: $domain) {
6+
edges {
7+
node {
8+
id
9+
externalId
10+
name
11+
storeType
12+
primaryDomain
13+
shortName
14+
url
1615
}
1716
}
18-
currentUser {
19-
organizationPermissions
20-
}
17+
}
18+
currentUser {
19+
organizationPermissions
2120
}
2221
}
22+
}
Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
query FetchStoreByDomain($domain: String) {
2-
organization {
3-
id
4-
name
5-
accessibleShops(search: $domain) {
6-
edges {
7-
node {
8-
id
9-
externalId
10-
name
11-
storeType
12-
primaryDomain
13-
shortName
14-
url
15-
}
1+
query FetchStoreByDomain($domain: String) {
2+
organization {
3+
id
4+
name
5+
accessibleShops(search: $domain) {
6+
edges {
7+
node {
8+
id
9+
externalId
10+
name
11+
storeType
12+
primaryDomain
13+
shortName
14+
url
1615
}
1716
}
18-
currentUser {
19-
organizationPermissions
20-
}
17+
}
18+
currentUser {
19+
organizationPermissions
2120
}
2221
}
22+
}

packages/app/src/cli/services/bulk-operations/execute-bulk-operation.test.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {BULK_OPERATIONS_MIN_API_VERSION} from './constants.js'
77
import {resolveApiVersion} from '../graphql/common.js'
88
import {BulkOperationRunQueryMutation} from '../../api/graphql/bulk-operations/generated/bulk-operation-run-query.js'
99
import {BulkOperationRunMutationMutation} from '../../api/graphql/bulk-operations/generated/bulk-operation-run-mutation.js'
10-
import {OrganizationApp, OrganizationSource} from '../../models/organization.js'
10+
import {OrganizationApp, OrganizationSource, OrganizationStore} from '../../models/organization.js'
1111
import {renderSuccess, renderWarning, renderError, renderInfo} from '@shopify/cli-kit/node/ui'
1212
import {ensureAuthenticatedAdminAsApp} from '@shopify/cli-kit/node/session'
1313
import {inTemporaryDirectory, writeFile} from '@shopify/cli-kit/node/fs'
@@ -24,6 +24,7 @@ vi.mock('../graphql/common.js', async () => {
2424
return {
2525
...actual,
2626
resolveApiVersion: vi.fn(),
27+
validateMutationStore: vi.fn(),
2728
}
2829
})
2930
vi.mock('@shopify/cli-kit/node/ui')
@@ -50,15 +51,14 @@ describe('executeBulkOperation', () => {
5051
} as OrganizationApp
5152

5253
const storeFqdn = 'test-store.myshopify.com'
53-
const mockStore = {
54+
const mockStore: OrganizationStore = {
5455
shopId: '123',
55-
link: 'link',
56+
link: 'https://test-store.myshopify.com/admin',
5657
shopDomain: storeFqdn,
5758
shopName: 'Test Store',
58-
transferDisabled: true,
59+
transferDisabled: false,
5960
convertableToPartnerTest: false,
6061
provisionable: true,
61-
storeType: 'APP_DEVELOPMENT',
6262
}
6363
const mockAdminSession = {token: 'test-token', storeFqdn}
6464

@@ -413,7 +413,7 @@ describe('executeBulkOperation', () => {
413413
await executeBulkOperation({
414414
organization: mockOrganization,
415415
remoteApp: mockRemoteApp,
416-
storeFqdn,
416+
store: mockStore,
417417
query,
418418
watch: false,
419419
})
@@ -440,7 +440,7 @@ describe('executeBulkOperation', () => {
440440
await executeBulkOperation({
441441
organization: mockOrganization,
442442
remoteApp: mockRemoteApp,
443-
storeFqdn,
443+
store: mockStore,
444444
query,
445445
watch: false,
446446
})
@@ -600,7 +600,7 @@ describe('executeBulkOperation', () => {
600600
await executeBulkOperation({
601601
organization: mockOrganization,
602602
remoteApp: mockRemoteApp,
603-
storeFqdn,
603+
store: mockStore,
604604
query,
605605
watch: true,
606606
})
@@ -636,7 +636,7 @@ describe('executeBulkOperation', () => {
636636
await executeBulkOperation({
637637
organization: mockOrganization,
638638
remoteApp: mockRemoteApp,
639-
storeFqdn,
639+
store: mockStore,
640640
query,
641641
watch: true,
642642
})
@@ -672,7 +672,7 @@ describe('executeBulkOperation', () => {
672672
await executeBulkOperation({
673673
organization: mockOrganization,
674674
remoteApp: mockRemoteApp,
675-
storeFqdn,
675+
store: mockStore,
676676
query,
677677
watch: true,
678678
outputFile,

packages/app/src/cli/services/execute-operation.test.ts

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {executeOperation} from './execute-operation.js'
2-
import {createAdminSessionAsApp, resolveApiVersion} from './graphql/common.js'
3-
import {OrganizationApp, OrganizationSource} from '../models/organization.js'
2+
import {createAdminSessionAsApp, resolveApiVersion, validateMutationStore} from './graphql/common.js'
3+
import {OrganizationApp, OrganizationSource, OrganizationStore} from '../models/organization.js'
44
import {renderSuccess, renderError, renderSingleTask} from '@shopify/cli-kit/node/ui'
55
import {adminRequestDoc} from '@shopify/cli-kit/node/api/admin'
66
import {ClientError} from 'graphql-request'
@@ -28,12 +28,12 @@ describe('executeOperation', () => {
2828
} as OrganizationApp
2929

3030
const storeFqdn = 'test-store.myshopify.com'
31-
const mockStore = {
31+
const mockStore: OrganizationStore = {
3232
shopId: '123',
33-
link: 'link',
33+
link: 'https://test-store.myshopify.com/admin',
3434
shopDomain: storeFqdn,
3535
shopName: 'Test Store',
36-
transferDisabled: true,
36+
transferDisabled: false,
3737
convertableToPartnerTest: false,
3838
provisionable: true,
3939
storeType: 'APP_DEVELOPMENT',
@@ -127,7 +127,7 @@ describe('executeOperation', () => {
127127
await executeOperation({
128128
organization: mockOrganization,
129129
remoteApp: mockRemoteApp,
130-
storeFqdn,
130+
store: mockStore,
131131
query,
132132
variableFile,
133133
})
@@ -149,7 +149,7 @@ describe('executeOperation', () => {
149149
executeOperation({
150150
organization: mockOrganization,
151151
remoteApp: mockRemoteApp,
152-
storeFqdn,
152+
store: mockStore,
153153
query,
154154
variableFile: nonExistentFile,
155155
}),
@@ -170,7 +170,7 @@ describe('executeOperation', () => {
170170
executeOperation({
171171
organization: mockOrganization,
172172
remoteApp: mockRemoteApp,
173-
storeFqdn,
173+
store: mockStore,
174174
query,
175175
variableFile,
176176
}),
@@ -327,4 +327,37 @@ describe('executeOperation', () => {
327327
}),
328328
)
329329
})
330+
331+
test('throws AbortError when attempting mutation on non-dev store', async () => {
332+
const nonDevStore: OrganizationStore = {
333+
shopId: '456',
334+
link: 'https://prod-store.myshopify.com/admin',
335+
shopDomain: 'prod-store.myshopify.com',
336+
shopName: 'Production Store',
337+
transferDisabled: false,
338+
convertableToPartnerTest: false,
339+
provisionable: false,
340+
storeType: 'PRODUCTION',
341+
}
342+
343+
const mutation = 'mutation { productUpdate(input: {}) { product { id } } }'
344+
345+
// Import the real validateMutationStore to test end-to-end validation
346+
const {validateMutationStore: realValidateMutationStore} = await vi.importActual<
347+
typeof import('./graphql/common.js')
348+
>('./graphql/common.js')
349+
vi.mocked(validateMutationStore).mockImplementation((query, store) => realValidateMutationStore(query, store))
350+
351+
await expect(
352+
executeOperation({
353+
organization: mockOrganization,
354+
remoteApp: mockRemoteApp,
355+
store: nonDevStore,
356+
query: mutation,
357+
}),
358+
).rejects.toThrow('Mutations can only be executed on dev stores')
359+
360+
// Verify no API call was made - validation should fail before reaching the API
361+
expect(adminRequestDoc).not.toHaveBeenCalled()
362+
})
330363
})

packages/app/src/cli/utilities/developer-platform-client.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,11 @@ export interface DeveloperPlatformClient {
250250
templateSpecifications: (app: MinimalAppIdentifiers) => Promise<ExtensionTemplatesResult>
251251
createApp: (org: Organization, options: CreateAppOptions) => Promise<OrganizationApp>
252252
devStoresForOrg: (orgId: string, searchTerm?: string) => Promise<Paginateable<{stores: OrganizationStore[]}>>
253-
storeByDomain: (orgId: string, shopDomain: string, includeAllStores?: boolean) => Promise<OrganizationStore | undefined>
253+
storeByDomain: (
254+
orgId: string,
255+
shopDomain: string,
256+
includeAllStores?: boolean,
257+
) => Promise<OrganizationStore | undefined>
254258
ensureUserAccessToStore: (orgId: string, store: OrganizationStore) => Promise<void>
255259
appExtensionRegistrations: (
256260
app: MinimalAppIdentifiers,

0 commit comments

Comments
 (0)