Skip to content

Commit 3bb514a

Browse files
authored
Merge pull request #6740 from Shopify/update-ink
Update ink to 5.2.1
2 parents 7297a1f + 64d4c58 commit 3bb514a

File tree

24 files changed

+217
-199
lines changed

24 files changed

+217
-199
lines changed

.changeset/update-ink.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@shopify/cli-kit": patch
3+
---
4+
5+
Update ink from 4.4.1 to 5.2.1

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@
7474
"octokit-plugin-create-pull-request": "^3.12.2",
7575
"pathe": "1.1.1",
7676
"pin-github-action": "^3.3.1",
77-
"react": "17.0.2",
7877
"rimraf": "^3.0.2",
7978
"tmp": "^0.2.5",
8079
"ts-node": "^10.9.1",
@@ -98,7 +97,7 @@
9897
},
9998
"version": "0.0.0",
10099
"resolutions": {
101-
"@types/react": "17.0.2",
100+
"@types/react": "18.3.12",
102101
"vite": "6.4.1",
103102
"whatwg-url": "14.0.0",
104103
"supports-hyperlinks": "3.1.0",
@@ -162,7 +161,6 @@
162161
"@nx/workspace",
163162
"graphql-tag",
164163
"pin-github-action",
165-
"react",
166164
"esbuild"
167165
],
168166
"ignore": [

packages/app/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@
7979
"@types/diff": "^5.0.3",
8080
"@types/express": "^4.17.17",
8181
"@types/proper-lockfile": "4.1.4",
82-
"@types/react": "18.2.0",
83-
"@types/react-dom": "18.2.0",
82+
"@types/react": "^18.2.0",
83+
"@types/react-dom": "^18.2.0",
8484
"@types/which": "3.0.4",
8585
"@types/ws": "^8.5.13",
8686
"@vitest/coverage-istanbul": "^3.1.4"

packages/app/src/cli/services/app-logs/logs-command/ui/components/Logs.tsx

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ const Logs: FunctionComponent<LogsProps> = ({
7777
</Box>
7878
<Box flexDirection="column" marginLeft={4}>
7979
{appLog instanceof FunctionRunLog && (
80-
<>
80+
<Box flexDirection="column">
8181
<Text>{appLog.logs}</Text>
82-
{appLog.inputQueryVariablesMetafieldKey && appLog.inputQueryVariablesMetafieldNamespace && (
82+
{appLog.inputQueryVariablesMetafieldKey && appLog.inputQueryVariablesMetafieldNamespace ? (
8383
<Box flexDirection="column" marginTop={1}>
8484
<Text bold>Input Query Variables:</Text>
8585
<Box flexDirection="row" marginLeft={1} marginTop={1}>
@@ -98,8 +98,8 @@ const Logs: FunctionComponent<LogsProps> = ({
9898
</Text>
9999
</Box>
100100
</Box>
101-
)}
102-
{appLog.input && (
101+
) : null}
102+
{appLog.input ? (
103103
<Box flexDirection="column" marginTop={1}>
104104
<Text bold>
105105
Input <Text dimColor>({appLog.inputBytes} bytes):</Text>
@@ -108,8 +108,8 @@ const Logs: FunctionComponent<LogsProps> = ({
108108
<Text>{prettyPrintJsonIfPossible(appLog.input)}</Text>
109109
</Box>
110110
</Box>
111-
)}
112-
{appLog.output && (
111+
) : null}
112+
{appLog.output ? (
113113
<Box flexDirection="column" marginTop={1}>
114114
<Text bold>
115115
Output <Text dimColor>({appLog.outputBytes} bytes):</Text>
@@ -118,41 +118,41 @@ const Logs: FunctionComponent<LogsProps> = ({
118118
<Text>{prettyPrintJsonIfPossible(appLog.output)}</Text>
119119
</Box>
120120
</Box>
121-
)}
122-
</>
121+
) : null}
122+
</Box>
123123
)}
124124
{appLog instanceof NetworkAccessResponseFromCacheLog && (
125-
<>
125+
<Box flexDirection="column">
126126
<Text>Cache write time: {new Date(appLog.cacheEntryEpochMs).toISOString()}</Text>
127127
<Text>Cache TTL: {appLog.cacheTtlMs / 1000} s</Text>
128128
<Text>HTTP request:</Text>
129129
<Text>{prettyPrintJsonIfPossible(appLog.httpRequest)}</Text>
130130
<Text>HTTP response:</Text>
131131
<Text>{prettyPrintJsonIfPossible(appLog.httpResponse)}</Text>
132-
</>
132+
</Box>
133133
)}
134134
{appLog instanceof NetworkAccessRequestExecutionInBackgroundLog && (
135-
<>
135+
<Box flexDirection="column">
136136
<Text>Reason: {getBackgroundExecutionReasonMessage(appLog.reason)}</Text>
137137
<Text>HTTP request:</Text>
138138
<Text>{prettyPrintJsonIfPossible(appLog.httpRequest)}</Text>
139-
</>
139+
</Box>
140140
)}
141141
{appLog instanceof NetworkAccessRequestExecutedLog && (
142-
<>
142+
<Box flexDirection="column">
143143
<Text>Attempt: {appLog.attempt}</Text>
144-
{appLog.connectTimeMs && <Text>Connect time: {appLog.connectTimeMs} ms</Text>}
145-
{appLog.writeReadTimeMs && <Text>Write read time: {appLog.writeReadTimeMs} ms</Text>}
144+
{appLog.connectTimeMs ? <Text>Connect time: {appLog.connectTimeMs} ms</Text> : null}
145+
{appLog.writeReadTimeMs ? <Text>Write read time: {appLog.writeReadTimeMs} ms</Text> : null}
146146
<Text>HTTP request:</Text>
147147
<Text>{prettyPrintJsonIfPossible(appLog.httpRequest)}</Text>
148-
{appLog.httpResponse && (
149-
<>
148+
{appLog.httpResponse ? (
149+
<Box flexDirection="column">
150150
<Text>HTTP response:</Text>
151151
<Text>{prettyPrintJsonIfPossible(appLog.httpResponse)}</Text>
152-
</>
153-
)}
154-
{appLog.error && <Text>Error: {appLog.error}</Text>}
155-
</>
152+
</Box>
153+
) : null}
154+
{appLog.error ? <Text>Error: {appLog.error}</Text> : null}
155+
</Box>
156156
)}
157157
</Box>
158158
</Box>

packages/app/src/cli/services/app-logs/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,15 +229,15 @@ export const subscribeToAppLogs = async (
229229
return jwtToken
230230
}
231231

232-
export function prettyPrintJsonIfPossible(json: unknown) {
232+
export function prettyPrintJsonIfPossible(json: unknown): string | undefined {
233233
try {
234234
if (typeof json === 'string') {
235235
const jsonObject = JSON.parse(json)
236236
return JSON.stringify(jsonObject, null, 2)
237237
} else if (typeof json === 'object' && json !== null) {
238238
return JSON.stringify(json, null, 2)
239239
} else {
240-
return json
240+
return undefined
241241
}
242242
} catch (error) {
243243
throw new Error(`Error parsing JSON: ${error as string}`)

packages/app/src/cli/services/dev/app-events/app-event-watcher-handler.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ async function reload(app: AppLinkedInterface): Promise<AppLinkedInterface> {
135135
return newApp
136136
// eslint-disable-next-line @typescript-eslint/no-explicit-any
137137
} catch (error: any) {
138-
throw new Error(`Error reloading app: ${error.message}`, {cause: 'validation-error'})
138+
const err = new Error(`Error reloading app: ${error.message}`) as Error & {cause: string}
139+
err.cause = 'validation-error'
140+
throw err
139141
}
140142
}

packages/app/src/cli/services/dev/processes/dev-session/dev-session-process.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ describe('pushUpdatesForDevSession', () => {
360360
test('sets validation error status message when error cause is validation-error', async () => {
361361
// Given
362362
const validationError = new Error('Validation failed')
363-
validationError.cause = 'validation-error'
363+
;(validationError as Error & {cause: string}).cause = 'validation-error'
364364

365365
// When
366366
await pushUpdatesForDevSession({stderr, stdout, abortSignal: abortController.signal}, options)

packages/app/src/cli/services/dev/processes/dev-session/dev-session.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ export class DevSession {
221221
await this.logger.debug('❌ Dev preview update aborted (new change detected or error during update)')
222222
} else if (result.status === 'remote-error' || result.status === 'unknown-error') {
223223
await this.logger.logUserErrors(result.error, event?.app.allExtensions ?? [])
224-
if (result.error instanceof Error && result.error.cause === 'validation-error') {
224+
if (result.error instanceof Error && (result.error as Error & {cause?: string}).cause === 'validation-error') {
225225
this.statusManager.setMessage('VALIDATION_ERROR')
226226
} else {
227227
if (event) this.failedEvents.push(event)

packages/app/src/cli/utilities/app/http-reverse-proxy.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import * as https from 'https'
66
import {Writable} from 'stream'
77
import type Server from 'http-proxy-node16'
88

9+
function isAggregateError(err: Error): err is Error & {errors: Error[]} {
10+
return 'errors' in err && Array.isArray((err as {errors?: unknown}).errors)
11+
}
12+
913
export interface LocalhostCert {
1014
key: string
1115
cert: string
@@ -47,7 +51,8 @@ function getProxyServerWebsocketUpgradeListener(
4751
if (target) {
4852
return proxy.ws(req, socket, head, {target}, (err) => {
4953
useConcurrentOutputContext({outputPrefix: 'proxy', stripAnsi: false}, () => {
50-
const error = err instanceof AggregateError && err.errors.length > 0 ? err.errors[err.errors.length - 1] : err
54+
const lastError = isAggregateError(err) ? err.errors[err.errors.length - 1] : undefined
55+
const error = lastError ?? err
5156
outputWarn(`Error forwarding websocket request: ${error.message}`, stdout)
5257
outputWarn(`└ Unreachable target "${target}" for path: "${req.url}"`, stdout)
5358
})
@@ -67,7 +72,8 @@ function getProxyServerRequestListener(
6772
if (target) {
6873
return proxy.web(req, res, {target}, (err) => {
6974
useConcurrentOutputContext({outputPrefix: 'proxy', stripAnsi: false}, () => {
70-
const error = err instanceof AggregateError && err.errors.length > 0 ? err.errors[err.errors.length - 1] : err
75+
const lastError = isAggregateError(err) ? err.errors[err.errors.length - 1] : undefined
76+
const error = lastError ?? err
7177
outputWarn(`Error forwarding web request: ${error.message}`, stdout)
7278
outputWarn(`└ Unreachable target "${target}" for path: "${req.url}"`, stdout)
7379
})

packages/cli-kit/bin/documentation/examples.ts

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -565,45 +565,64 @@ export const examples: {[key in string]: Example} = {
565565
renderTasks: {
566566
type: 'async',
567567
basic: async () => {
568-
const stdout = new Stdout({columns: TERMINAL_WIDTH})
568+
// Force colors for deterministic output (solid blocks vs animated wave)
569+
const originalForceColor = process.env.FORCE_COLOR
570+
process.env.FORCE_COLOR = '1'
571+
try {
572+
const stdout = new Stdout({columns: TERMINAL_WIDTH})
569573

570-
const tasks = [
571-
{
572-
title: 'Installing dependencies',
573-
task: async () => {
574-
await new Promise((resolve) => setTimeout(resolve, 2000))
574+
const tasks = [
575+
{
576+
title: 'Installing dependencies',
577+
task: async () => {
578+
await new Promise((resolve) => setTimeout(resolve, 2000))
579+
},
575580
},
576-
},
577-
]
578-
579-
renderTasks(tasks, {renderOptions: {stdout: stdout as any, debug: true}})
580-
581-
await waitFor(
582-
() => {},
583-
() => Boolean(stdout.lastFrame()?.includes('Installing dependencies')),
584-
)
585-
586-
return stdout.lastFrame()!
581+
]
582+
583+
renderTasks(tasks, {renderOptions: {stdout: stdout as any, debug: true}})
584+
585+
await waitFor(
586+
() => {},
587+
() => Boolean(stdout.lastFrame()?.includes('Installing dependencies')),
588+
)
589+
590+
return stdout.lastFrame()!
591+
} finally {
592+
if (originalForceColor === undefined) {
593+
delete process.env.FORCE_COLOR
594+
} else {
595+
process.env.FORCE_COLOR = originalForceColor
596+
}
597+
}
587598
},
588599
},
589600
renderSingleTask: {
590601
type: 'async',
591602
basic: async () => {
592-
const stdout = new Stdout({columns: TERMINAL_WIDTH})
593-
594-
await renderSingleTask({
595-
title: outputContent`Loading app`,
596-
task: async () => {
597-
await sleep(1)
598-
},
599-
renderOptions: {stdout: stdout as any, debug: true}
600-
})
601-
602-
// Find the last frame that includes mention of "Loading"
603-
const loadingFrame = stdout.frames.findLast(frame => frame.includes('Loading'))
604-
605-
// Gives a frame where the loading bar is visible
606-
return loadingFrame ?? stdout.lastFrame()!
603+
// Force colors for deterministic output (solid blocks vs animated wave)
604+
const originalForceColor = process.env.FORCE_COLOR
605+
process.env.FORCE_COLOR = '1'
606+
try {
607+
const stdout = new Stdout({columns: TERMINAL_WIDTH})
608+
609+
await renderSingleTask({
610+
title: outputContent`Loading app`,
611+
task: async () => {
612+
await sleep(1)
613+
},
614+
renderOptions: {stdout: stdout as any, debug: true},
615+
})
616+
617+
// Return first frame with the title for deterministic output
618+
return stdout.frames.find((frame) => frame.includes('Loading'))!
619+
} finally {
620+
if (originalForceColor === undefined) {
621+
delete process.env.FORCE_COLOR
622+
} else {
623+
process.env.FORCE_COLOR = originalForceColor
624+
}
625+
}
607626
},
608627
},
609628
renderTextPrompt: {

0 commit comments

Comments
 (0)