From 838bb83b99247820c58235a616c3c996d8107285 Mon Sep 17 00:00:00 2001 From: Josh Faigan Date: Fri, 1 Nov 2024 10:48:06 -0400 Subject: [PATCH] Add shortcut keys to theme dev This commit adds shortcut keys to the theme dev CLI service. The keys are as follows: e - open theme editor t - preview your theme locally p - preview your theme (share) g - preview gift cards --- .changeset/swift-frogs-fail.md | 5 ++ packages/theme/src/cli/services/dev.test.ts | 86 ++++++++++++--------- packages/theme/src/cli/services/dev.ts | 52 +++++++++++-- 3 files changed, 101 insertions(+), 42 deletions(-) create mode 100644 .changeset/swift-frogs-fail.md diff --git a/.changeset/swift-frogs-fail.md b/.changeset/swift-frogs-fail.md new file mode 100644 index 0000000000..9ab30173dc --- /dev/null +++ b/.changeset/swift-frogs-fail.md @@ -0,0 +1,5 @@ +--- +'@shopify/theme': minor +--- + +Add shortcut keys to theme dev commands diff --git a/packages/theme/src/cli/services/dev.test.ts b/packages/theme/src/cli/services/dev.test.ts index 678f9b30cf..7e86f65934 100644 --- a/packages/theme/src/cli/services/dev.test.ts +++ b/packages/theme/src/cli/services/dev.test.ts @@ -21,6 +21,13 @@ vi.mock('../utilities/theme-environment/storefront-session.js') vi.mock('../utilities/theme-environment/theme-environment.js') vi.mock('../utilities/theme-fs-empty.js') vi.mock('../utilities/theme-fs.js') +vi.mock('@shopify/cli-kit/node/colors', () => ({ + default: { + bold: (str: string) => str, + cyan: (str: string) => str, + gray: (str: string) => str, + }, +})) describe('dev', () => { const store = 'my-store.myshopify.com' @@ -95,51 +102,58 @@ describe('dev', () => { }) }) - describe('renderLinks', async () => { - test('renders "dev" command links', async () => { - // Given - const themeId = theme.id.toString() + test('renders "dev" command links', async () => { + // Given + const themeId = theme.id.toString() - // When - renderLinks(store, themeId) + // When + renderLinks(store, themeId) - // Then - expect(renderSuccess).toHaveBeenCalledWith({ - body: [ - { - list: { - items: ['http://127.0.0.1:9292'], - title: { - bold: 'Preview your theme', + // Then + expect(renderSuccess).toHaveBeenCalledWith({ + body: [ + { + list: { + title: 'Preview your theme (t)', + items: [ + { + link: { + url: 'http://127.0.0.1:9292', + }, }, + ], + }, + }, + ], + nextSteps: [ + [ + { + link: { + label: 'Preview your gift cards (g)', + url: 'http://127.0.0.1:9292/gift_cards/[store_id]/preview', }, }, ], - nextSteps: [ - [ - { - link: { - label: 'Preview your gift cards', - url: 'http://127.0.0.1:9292/gift_cards/[store_id]/preview', - }, - }, - ], - [ - { - link: { - label: 'Customize your theme at the theme editor', - url: 'https://my-store.myshopify.com/admin/themes/123/editor', - }, + [ + { + link: { + label: `Customize your theme at the theme editor (e)`, + url: `https://${store}/admin/themes/${themeId}/editor`, }, - ], - [ - 'Share your theme preview', - { - subdued: '\nhttps://my-store.myshopify.com/?preview_theme_id=123', + }, + ], + [ + { + link: { + label: `Share your theme preview (p)`, + url: `https://${store}/?preview_theme_id=${themeId}`, }, - ], + }, + { + subdued: `https://${store}/?preview_theme_id=${themeId}`, + }, ], - }) + ], }) }) }) diff --git a/packages/theme/src/cli/services/dev.ts b/packages/theme/src/cli/services/dev.ts index cdc3a9e987..e06db79956 100644 --- a/packages/theme/src/cli/services/dev.ts +++ b/packages/theme/src/cli/services/dev.ts @@ -12,6 +12,8 @@ import {Theme} from '@shopify/cli-kit/node/themes/types' import {checkPortAvailability, getAvailableTCPPort} from '@shopify/cli-kit/node/tcp' import {AbortError} from '@shopify/cli-kit/node/error' import {openURL} from '@shopify/cli-kit/node/system' +import chalk from '@shopify/cli-kit/node/colors' +import readline from 'readline' const DEFAULT_HOST = '127.0.0.1' const DEFAULT_PORT = '9292' @@ -104,6 +106,33 @@ export async function dev(options: DevOptions) { renderWarning({headline: 'Failed to open the development server.', body: error.stack ?? error.message}) }) } + + readline.emitKeypressEvents(process.stdin) + if (process.stdin.isTTY) { + process.stdin.setRawMode(true) + } + + process.stdin.on('keypress', (_str, key) => { + if (key.ctrl && key.name === 'c') { + process.exit() + } else if (key.name === 't') { + openURL(`http://${host}:${port}`).catch((error) => { + renderWarning({headline: 'Failed to open localhost.', body: error.stack ?? error.message}) + }) + } else if (key.name === 'e') { + openURL(`https://${options.store}/admin/themes/${options.theme.id}/editor`).catch((error) => { + renderWarning({headline: 'Failed to open theme editor.', body: error.stack ?? error.message}) + }) + } else if (key.name === 'p') { + openURL(`https://${options.store}/?preview_theme_id=${options.theme.id}`).catch((error) => { + renderWarning({headline: 'Failed to open theme preview.', body: error.stack ?? error.message}) + }) + } else if (key.name === 'g') { + openURL(`http://${host}:${port}/gift_cards/${options.store}/preview`).catch((error) => { + renderWarning({headline: 'Failed to open gift card preview.', body: error.stack ?? error.message}) + }) + } + }) } export function renderLinks(store: string, themeId: string, host = DEFAULT_HOST, port = DEFAULT_PORT) { @@ -113,8 +142,14 @@ export function renderLinks(store: string, themeId: string, host = DEFAULT_HOST, body: [ { list: { - title: {bold: 'Preview your theme'}, - items: [localUrl], + title: chalk.bold('Preview your theme ') + chalk.cyan('(t)'), + items: [ + { + link: { + url: localUrl, + }, + }, + ], }, }, ], @@ -122,7 +157,7 @@ export function renderLinks(store: string, themeId: string, host = DEFAULT_HOST, [ { link: { - label: 'Preview your gift cards', + label: `Preview your gift cards ${chalk.cyan('(g)')}`, url: `${localUrl}/gift_cards/[store_id]/preview`, }, }, @@ -130,15 +165,20 @@ export function renderLinks(store: string, themeId: string, host = DEFAULT_HOST, [ { link: { - label: 'Customize your theme at the theme editor', + label: `Customize your theme at the theme editor ${chalk.cyan('(e)')}`, url: `${remoteUrl}/admin/themes/${themeId}/editor`, }, }, ], [ - 'Share your theme preview', { - subdued: `\n${remoteUrl}/?preview_theme_id=${themeId}`, + link: { + label: `Share your theme preview ${chalk.cyan('(p)')}`, + url: `${remoteUrl}/?preview_theme_id=${themeId}`, + }, + }, + { + subdued: `${remoteUrl}/?preview_theme_id=${themeId}`, }, ], ],