Skip to content

Commit dbcb9d6

Browse files
Merge pull request #7199 from Shopify/fix-eslint-config
Fix eslint config
2 parents 897b69f + 31092f2 commit dbcb9d6

36 files changed

Lines changed: 176 additions & 203 deletions

packages/cli/project.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@
3737
"lint": {
3838
"executor": "nx:run-commands",
3939
"options": {
40-
"command": "pnpm eslint \"src/**/*.ts\" 'bin/*.js' ",
40+
"command": "pnpm eslint src 'bin/*.js'",
4141
"cwd": "packages/cli"
4242
}
4343
},
4444
"lint:fix": {
4545
"executor": "nx:run-commands",
4646
"options": {
47-
"command": "pnpm eslint 'src/**/*.ts' 'bin/*.js' --fix",
47+
"command": "pnpm eslint src 'bin/*.js' --fix",
4848
"cwd": "packages/cli"
4949
}
5050
},

packages/cli/src/cli/commands/docs/generate.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ export async function writeCommandDocumentation(
9090
const previewDescription = command.summary ?? description ?? ''
9191
const cleanPreview = previewDescription.replace(/`/g, '\\`').replace(/https:\/\/shopify\.dev/g, '')
9292

93-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
9493
const category = hasTopic && !generalTopics.includes(topic!) ? topic : 'general commands'
9594

9695
const docString = `// This is an autogenerated file. Don't edit this file manually.
@@ -139,7 +138,7 @@ export async function writeCommandFlagInterface(
139138
const flag = command.flags[flagName]
140139
if (!flag) return
141140
if (flag.hidden) return
142-
const flagDescription = flag.description || ''
141+
const flagDescription = flag.description ?? ''
143142
const char = flag.char ? `-${flag.char}, ` : ''
144143
const type = flag.type === 'option' ? 'string' : "''"
145144
const value = flag.type === 'option' ? ' <value>' : ''

packages/cli/src/cli/commands/store/auth.test.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
1-
import {beforeEach, describe, expect, test, vi} from 'vitest'
21
import StoreAuth from './auth.js'
32
import {authenticateStoreWithApp} from '../../services/store/auth/index.js'
43
import {createStoreAuthPresenter} from '../../services/store/auth/result.js'
4+
import {describe, expect, test, vi} from 'vitest'
55

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

1111
describe('store auth command', () => {
12-
beforeEach(() => {
13-
vi.clearAllMocks()
14-
})
15-
1612
test('passes parsed flags through to the auth service', async () => {
1713
await StoreAuth.run(['--store', 'shop.myshopify.com', '--scopes', 'read_products,write_products'])
1814

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
import {authenticateStoreWithApp} from '../../services/store/auth/index.js'
2+
import {createStoreAuthPresenter} from '../../services/store/auth/result.js'
13
import Command from '@shopify/cli-kit/node/base-command'
24
import {globalFlags, jsonFlag} from '@shopify/cli-kit/node/cli'
35
import {normalizeStoreFqdn} from '@shopify/cli-kit/node/context/fqdn'
46
import {Flags} from '@oclif/core'
5-
import {authenticateStoreWithApp} from '../../services/store/auth/index.js'
6-
import {createStoreAuthPresenter} from '../../services/store/auth/result.js'
77

88
export default class StoreAuth extends Command {
99
static summary = 'Authenticate an app against a store for store commands.'

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

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
import {beforeEach, describe, expect, test, vi} from 'vitest'
21
import StoreExecute from './execute.js'
32
import {executeStoreOperation} from '../../services/store/execute/index.js'
43
import {writeOrOutputStoreExecuteResult} from '../../services/store/execute/result.js'
4+
import {beforeEach, describe, expect, test, vi} from 'vitest'
55

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

99
describe('store execute command', () => {
1010
beforeEach(() => {
11-
vi.clearAllMocks()
1211
vi.mocked(executeStoreOperation).mockResolvedValue({data: {shop: {name: 'Test shop'}}})
1312
})
1413

@@ -24,11 +23,7 @@ describe('store execute command', () => {
2423
version: undefined,
2524
allowMutations: false,
2625
})
27-
expect(writeOrOutputStoreExecuteResult).toHaveBeenCalledWith(
28-
{data: {shop: {name: 'Test shop'}}},
29-
undefined,
30-
'text',
31-
)
26+
expect(writeOrOutputStoreExecuteResult).toHaveBeenCalledWith({data: {shop: {name: 'Test shop'}}}, undefined, 'text')
3227
})
3328

3429
test('passes the query file through to the service', async () => {
@@ -46,11 +41,7 @@ describe('store execute command', () => {
4641
test('writes json output when --json is provided', async () => {
4742
await StoreExecute.run(['--store', 'shop.myshopify.com', '--query', 'query { shop { name } }', '--json'])
4843

49-
expect(writeOrOutputStoreExecuteResult).toHaveBeenCalledWith(
50-
{data: {shop: {name: 'Test shop'}}},
51-
undefined,
52-
'json',
53-
)
44+
expect(writeOrOutputStoreExecuteResult).toHaveBeenCalledWith({data: {shop: {name: 'Test shop'}}}, undefined, 'json')
5445
})
5546

5647
test('defines the expected flags', () => {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
import {executeStoreOperation} from '../../services/store/execute/index.js'
2+
import {writeOrOutputStoreExecuteResult} from '../../services/store/execute/result.js'
13
import Command from '@shopify/cli-kit/node/base-command'
24
import {globalFlags, jsonFlag} from '@shopify/cli-kit/node/cli'
35
import {normalizeStoreFqdn} from '@shopify/cli-kit/node/context/fqdn'
46
import {resolvePath} from '@shopify/cli-kit/node/path'
57
import {Flags} from '@oclif/core'
6-
import {executeStoreOperation} from '../../services/store/execute/index.js'
7-
import {writeOrOutputStoreExecuteResult} from '../../services/store/execute/result.js'
88

99
export default class StoreExecute extends Command {
1010
static summary = 'Execute GraphQL queries and mutations on a store.'

packages/cli/src/cli/services/kitchen-sink/static.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export async function staticService() {
3535
})
3636

3737
renderInfo({
38-
headline: 'About your app',
38+
headline: 'About your app.',
3939
customSections: [
4040
{
4141
body: {

packages/cli/src/cli/services/store/auth/callback.test.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import {createServer} from 'http'
2-
import {describe, expect, test} from 'vitest'
31
import {waitForStoreAuthCode} from './callback.js'
2+
import {describe, expect, test} from 'vitest'
3+
import {createServer} from 'http'
44

55
async function getAvailablePort(): Promise<number> {
6-
return await new Promise<number>((resolve, reject) => {
6+
return new Promise<number>((resolve, reject) => {
77
const server = createServer()
88

99
server.on('error', reject)
@@ -26,12 +26,7 @@ async function getAvailablePort(): Promise<number> {
2626
})
2727
}
2828

29-
function callbackParams(options?: {
30-
code?: string
31-
shop?: string
32-
state?: string
33-
error?: string
34-
}): URLSearchParams {
29+
function callbackParams(options?: {code?: string; shop?: string; state?: string; error?: string}): URLSearchParams {
3530
const params = new URLSearchParams()
3631
params.set('shop', options?.shop ?? 'shop.myshopify.com')
3732
params.set('state', options?.state ?? 'state-123')
@@ -101,7 +96,8 @@ describe('store auth callback server', () => {
10196
}),
10297
).rejects.toMatchObject({
10398
message: 'OAuth callback store does not match the requested store.',
104-
tryMessage: 'Shopify returned other-shop.myshopify.com during authentication. Re-run using the permanent store domain:',
99+
tryMessage:
100+
'Shopify returned other-shop.myshopify.com during authentication. Re-run using the permanent store domain:',
105101
nextSteps: [[{command: 'shopify store auth --store other-shop.myshopify.com --scopes <comma-separated-scopes>'}]],
106102
})
107103
})

packages/cli/src/cli/services/store/auth/callback.ts

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
import {STORE_AUTH_CALLBACK_PATH, maskToken} from './config.js'
2+
import {retryStoreAuthWithPermanentDomainError} from './recovery.js'
13
import {normalizeStoreFqdn} from '@shopify/cli-kit/node/context/fqdn'
24
import {AbortError} from '@shopify/cli-kit/node/error'
35
import {outputContent, outputDebug, outputToken} from '@shopify/cli-kit/node/output'
46
import {timingSafeEqual} from 'crypto'
57
import {createServer} from 'http'
6-
import {STORE_AUTH_CALLBACK_PATH, maskToken} from './config.js'
7-
import {retryStoreAuthWithPermanentDomainError} from './recovery.js'
88

99
export interface WaitForAuthCodeOptions {
1010
store: string
@@ -15,16 +15,8 @@ export interface WaitForAuthCodeOptions {
1515
}
1616

1717
function renderAuthCallbackPage(title: string, message: string): string {
18-
const safeTitle = title
19-
.replace(/&/g, '&amp;')
20-
.replace(/</g, '&lt;')
21-
.replace(/>/g, '&gt;')
22-
.replace(/"/g, '&quot;')
23-
const safeMessage = message
24-
.replace(/&/g, '&amp;')
25-
.replace(/</g, '&lt;')
26-
.replace(/>/g, '&gt;')
27-
.replace(/"/g, '&quot;')
18+
const safeTitle = title.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;')
19+
const safeMessage = message.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;')
2820

2921
return `<!doctype html>
3022
<html lang="en">
@@ -120,7 +112,9 @@ export async function waitForStoreAuthCode({
120112
res.setHeader('Content-Type', 'text/html')
121113
res.setHeader('Connection', 'close')
122114
res.once('finish', () => settle(() => resolve(code)))
123-
res.end(renderAuthCallbackPage('Authentication succeeded', 'You can close this window and return to the terminal.'))
115+
res.end(
116+
renderAuthCallbackPage('Authentication succeeded', 'You can close this window and return to the terminal.'),
117+
)
124118
})
125119

126120
const settle = (callback: () => void) => {
@@ -162,24 +156,22 @@ export async function waitForStoreAuthCode({
162156
settleWithError(error)
163157
})
164158

165-
server.listen(port, '127.0.0.1', async () => {
159+
server.listen(port, '127.0.0.1', () => {
166160
isListening = true
167161
outputDebug(
168162
outputContent`PKCE callback server listening on http://127.0.0.1:${outputToken.raw(String(port))}${outputToken.raw(STORE_AUTH_CALLBACK_PATH)}`,
169163
)
170164

171165
if (!onListening) return
172166

173-
try {
174-
await onListening()
175-
} catch (error) {
167+
Promise.resolve(onListening()).catch((error: unknown) => {
176168
settleWithError(error instanceof Error ? error : new Error(String(error)))
177-
}
169+
})
178170
})
179171
})
180172
}
181173

182-
function constantTimeEqual(a: string, b: string): boolean {
183-
if (a.length !== b.length) return false
184-
return timingSafeEqual(Buffer.from(a, 'utf8'), Buffer.from(b, 'utf8'))
174+
function constantTimeEqual(left: string, right: string): boolean {
175+
if (left.length !== right.length) return false
176+
return timingSafeEqual(Buffer.from(left, 'utf8'), Buffer.from(right, 'utf8'))
185177
}

packages/cli/src/cli/services/store/auth/existing-scopes.test.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
import {afterEach, beforeEach, describe, expect, test, vi} from 'vitest'
2-
import {adminUrl} from '@shopify/cli-kit/node/api/admin'
3-
import {graphqlRequest} from '@shopify/cli-kit/node/api/graphql'
4-
import {mockAndCaptureOutput} from '@shopify/cli-kit/node/testing/output'
51
import {STORE_AUTH_APP_CLIENT_ID} from './config.js'
62
import {resolveExistingStoreAuthScopes} from './existing-scopes.js'
73
import {loadStoredStoreSession} from './session-lifecycle.js'
84
import {getCurrentStoredStoreAppSession} from './session-store.js'
5+
import {afterEach, beforeEach, describe, expect, test, vi} from 'vitest'
6+
import {adminUrl} from '@shopify/cli-kit/node/api/admin'
7+
import {graphqlRequest} from '@shopify/cli-kit/node/api/graphql'
8+
import {mockAndCaptureOutput} from '@shopify/cli-kit/node/testing/output'
99

1010
vi.mock('./session-store.js')
1111
vi.mock('./session-lifecycle.js', () => ({loadStoredStoreSession: vi.fn()}))
1212
vi.mock('@shopify/cli-kit/node/api/graphql')
1313
vi.mock('@shopify/cli-kit/node/api/admin', async () => {
14-
const actual = await vi.importActual<typeof import('@shopify/cli-kit/node/api/admin')>('@shopify/cli-kit/node/api/admin')
14+
const actual = await vi.importActual<typeof import('@shopify/cli-kit/node/api/admin')>(
15+
'@shopify/cli-kit/node/api/admin',
16+
)
1517
return {
1618
...actual,
1719
adminUrl: vi.fn(),
@@ -20,19 +22,20 @@ vi.mock('@shopify/cli-kit/node/api/admin', async () => {
2022

2123
describe('resolveExistingStoreAuthScopes', () => {
2224
beforeEach(() => {
23-
vi.clearAllMocks()
2425
vi.mocked(adminUrl).mockReturnValue('https://shop.myshopify.com/admin/api/unstable/graphql.json')
2526
})
2627

2728
afterEach(() => {
28-
vi.restoreAllMocks()
2929
mockAndCaptureOutput().clear()
3030
})
3131

3232
test('returns no scopes when no stored auth exists', async () => {
3333
vi.mocked(getCurrentStoredStoreAppSession).mockReturnValue(undefined)
3434

35-
await expect(resolveExistingStoreAuthScopes('shop.myshopify.com')).resolves.toEqual({scopes: [], authoritative: true})
35+
await expect(resolveExistingStoreAuthScopes('shop.myshopify.com')).resolves.toEqual({
36+
scopes: [],
37+
authoritative: true,
38+
})
3639
expect(loadStoredStoreSession).not.toHaveBeenCalled()
3740
expect(graphqlRequest).not.toHaveBeenCalled()
3841
})
@@ -120,7 +123,8 @@ describe('resolveExistingStoreAuthScopes', () => {
120123
errors: '[API] Invalid API key or access token (unrecognized login or wrong password)',
121124
},
122125
request: {
123-
query: '#graphql query CurrentAppInstallationAccessScopes { currentAppInstallation { accessScopes { handle } } }',
126+
query:
127+
'#graphql query CurrentAppInstallationAccessScopes { currentAppInstallation { accessScopes { handle } } }',
124128
},
125129
})
126130
vi.mocked(graphqlRequest).mockRejectedValue(scopeLookupError)
@@ -129,7 +133,9 @@ describe('resolveExistingStoreAuthScopes', () => {
129133
scopes: ['read_orders'],
130134
authoritative: false,
131135
})
132-
expect(output.debug()).toContain('after remote scope lookup failed: HTTP 401: [API] Invalid API key or access token')
136+
expect(output.debug()).toContain(
137+
'after remote scope lookup failed: HTTP 401: [API] Invalid API key or access token',
138+
)
133139
expect(output.debug()).not.toContain('CurrentAppInstallationAccessScopes')
134140
})
135141

0 commit comments

Comments
 (0)