From 6324dd7fde8282dc5f6faa1ea298fd97b392e5a4 Mon Sep 17 00:00:00 2001 From: Gonzalo Riestra Date: Fri, 16 Oct 2026 16:26:41 +0200 Subject: [PATCH] Add typed JSON output to autocorrect on --- .changeset/autocorrect-on-json.md | 5 +++ .../generated/generated_docs_data_v2.json | 38 ++++++++++++++++- packages/cli/README.md | 42 ++++++++++++++++++- packages/cli/oclif.manifest.json | 38 +++++++++++++++-- .../rules/json-output-command-exceptions.js | 1 - .../config/autocorrect/autocorrect.test.ts | 6 ++- .../commands/config/autocorrect/on.test.ts | 4 +- .../src/commands/config/autocorrect/on.ts | 21 +++++++--- .../src/services/autocorrect/index.test.ts | 21 +++++++++- .../src/services/autocorrect/index.ts | 7 +++- 10 files changed, 165 insertions(+), 18 deletions(-) create mode 100644 .changeset/autocorrect-on-json.md diff --git a/.changeset/autocorrect-on-json.md b/.changeset/autocorrect-on-json.md new file mode 100644 index 00000000000..a2fa1b9428f --- /dev/null +++ b/.changeset/autocorrect-on-json.md @@ -0,0 +1,5 @@ +--- +'@shopify/cli': minor +--- + +Add typed JSON output to `config autocorrect on`. diff --git a/docs-shopify.dev/generated/generated_docs_data_v2.json b/docs-shopify.dev/generated/generated_docs_data_v2.json index 0604d47b8f3..b5c94ededa1 100644 --- a/docs-shopify.dev/generated/generated_docs_data_v2.json +++ b/docs-shopify.dev/generated/generated_docs_data_v2.json @@ -5129,9 +5129,45 @@ "description": "Print the command's JSON schemas.", "isOptional": true, "environmentValue": "SHOPIFY_FLAG_JSON_SCHEMA" + }, + { + "filePath": "docs-shopify.dev/commands/interfaces/config-autocorrect-on.interface.ts", + "syntaxKind": "PropertySignature", + "name": "--no-color", + "value": "''", + "description": "Disable color output.", + "isOptional": true, + "environmentValue": "SHOPIFY_FLAG_NO_COLOR" + }, + { + "filePath": "docs-shopify.dev/commands/interfaces/config-autocorrect-on.interface.ts", + "syntaxKind": "PropertySignature", + "name": "--no-input", + "value": "''", + "description": "Disable interactive prompts and browser authentication.", + "isOptional": true, + "environmentValue": "SHOPIFY_FLAG_NO_INPUT" + }, + { + "filePath": "docs-shopify.dev/commands/interfaces/config-autocorrect-on.interface.ts", + "syntaxKind": "PropertySignature", + "name": "--verbose", + "value": "''", + "description": "Increase the verbosity of the output. May include sensitive data.", + "isOptional": true, + "environmentValue": "SHOPIFY_FLAG_VERBOSE" + }, + { + "filePath": "docs-shopify.dev/commands/interfaces/config-autocorrect-on.interface.ts", + "syntaxKind": "PropertySignature", + "name": "-j, --json", + "value": "''", + "description": "Output the result as JSON. Automatically disables color output.", + "isOptional": true, + "environmentValue": "SHOPIFY_FLAG_JSON" } ], - "value": "export interface configautocorrecton {\n /**\n * Print the command's JSON schemas.\n * @environment SHOPIFY_FLAG_JSON_SCHEMA\n */\n '--json-schema'?: ''\n}" + "value": "export interface configautocorrecton {\n /**\n * Output the result as JSON. Automatically disables color output.\n * @environment SHOPIFY_FLAG_JSON\n */\n '-j, --json'?: ''\n\n /**\n * Print the command's JSON schemas.\n * @environment SHOPIFY_FLAG_JSON_SCHEMA\n */\n '--json-schema'?: ''\n\n /**\n * Disable color output.\n * @environment SHOPIFY_FLAG_NO_COLOR\n */\n '--no-color'?: ''\n\n /**\n * Disable interactive prompts and browser authentication.\n * @environment SHOPIFY_FLAG_NO_INPUT\n */\n '--no-input'?: ''\n\n /**\n * Increase the verbosity of the output. May include sensitive data.\n * @environment SHOPIFY_FLAG_VERBOSE\n */\n '--verbose'?: ''\n}" } }, "configautocorrectstatus": { diff --git a/packages/cli/README.md b/packages/cli/README.md index 4a35048d824..8ab235f0556 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -5016,7 +5016,7 @@ FLAGS [env: SHOPIFY_FLAG_NAME] -p, --path= - [default: .] [env: SHOPIFY_FLAG_PATH] + [default: ./packages/cli] [env: SHOPIFY_FLAG_PATH] --auth-alias= Alias of the Shopify account to use for authentication. @@ -8086,13 +8086,29 @@ Enable autocorrect. Off by default. ``` USAGE - $ shopify config autocorrect on [--json-schema] + $ shopify config autocorrect on [-j] [--json-schema] [--no-color] [--no-input] [--verbose] FLAGS + -j, --json + Output the result as JSON. Automatically disables color output. + [env: SHOPIFY_FLAG_JSON] + --json-schema Print the command's JSON schemas. [env: SHOPIFY_FLAG_JSON_SCHEMA] + --no-color + Disable color output. + [env: SHOPIFY_FLAG_NO_COLOR] + + --no-input + Disable interactive prompts and browser authentication. + [env: SHOPIFY_FLAG_NO_INPUT] + + --verbose + Increase the verbosity of the output. May include sensitive data. + [env: SHOPIFY_FLAG_VERBOSE] + DESCRIPTION Enable autocorrect. Off by default. @@ -8102,6 +8118,28 @@ DESCRIPTION available. When autocorrection is disabled, you need to confirm that you want to run corrections for mistyped commands. + + + Use `--json-schema` to print the result, error, and event schemas. + + Output from `--json` conforms to the `AutocorrectResult` schema. + + ```json + { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + }, + "required": [ + "enabled" + ], + "additionalProperties": false, + "title": "AutocorrectResult", + "$schema": "http://json-schema.org/draft-07/schema#" + } + ``` ``` ## `shopify config autocorrect status` diff --git a/packages/cli/oclif.manifest.json b/packages/cli/oclif.manifest.json index 085d81e8d69..1146797bda4 100644 --- a/packages/cli/oclif.manifest.json +++ b/packages/cli/oclif.manifest.json @@ -3760,7 +3760,7 @@ }, "path": { "char": "p", - "default": ".", + "default": "./packages/cli", "env": "SHOPIFY_FLAG_PATH", "hasDynamicHelp": false, "hidden": false, @@ -6032,16 +6032,48 @@ "args": { }, "customPluginName": "@shopify/plugin-did-you-mean", - "description": "Enable autocorrect. Off by default.\n\n When autocorrection is enabled, Shopify CLI automatically runs a corrected version of your command if a correction is available.\n\n When autocorrection is disabled, you need to confirm that you want to run corrections for mistyped commands.\n", + "description": "Enable autocorrect. Off by default.\n\n When autocorrection is enabled, Shopify CLI automatically runs a corrected version of your command if a correction is available.\n\n When autocorrection is disabled, you need to confirm that you want to run corrections for mistyped commands.\n\n\nUse `--json-schema` to print the result, error, and event schemas.\n\nOutput from `--json` conforms to the `AutocorrectResult` schema.\n\n```json\n{\n \"type\": \"object\",\n \"properties\": {\n \"enabled\": {\n \"type\": \"boolean\"\n }\n },\n \"required\": [\n \"enabled\"\n ],\n \"additionalProperties\": false,\n \"title\": \"AutocorrectResult\",\n \"$schema\": \"http://json-schema.org/draft-07/schema#\"\n}\n```", "descriptionWithMarkdown": "Enable autocorrect. Off by default.\n\n When autocorrection is enabled, Shopify CLI automatically runs a corrected version of your command if a correction is available.\n\n When autocorrection is disabled, you need to confirm that you want to run corrections for mistyped commands.\n", "enableJsonFlag": false, "flags": { + "json": { + "allowNo": false, + "char": "j", + "description": "Output the result as JSON. Automatically disables color output.", + "env": "SHOPIFY_FLAG_JSON", + "hidden": false, + "name": "json", + "type": "boolean" + }, "json-schema": { "allowNo": false, "description": "Print the command's JSON schemas.", "env": "SHOPIFY_FLAG_JSON_SCHEMA", "name": "json-schema", "type": "boolean" + }, + "no-color": { + "allowNo": false, + "description": "Disable color output.", + "env": "SHOPIFY_FLAG_NO_COLOR", + "hidden": false, + "name": "no-color", + "type": "boolean" + }, + "no-input": { + "allowNo": false, + "description": "Disable interactive prompts and browser authentication.", + "env": "SHOPIFY_FLAG_NO_INPUT", + "name": "no-input", + "type": "boolean" + }, + "verbose": { + "allowNo": false, + "description": "Increase the verbosity of the output. May include sensitive data.", + "env": "SHOPIFY_FLAG_VERBOSE", + "hidden": false, + "name": "verbose", + "type": "boolean" } }, "hasDynamicHelp": false, @@ -6713,7 +6745,7 @@ }, "path": { "char": "p", - "default": ".", + "default": "./packages/cli", "description": "The path to run tests in. Defaults to current directory.", "env": "SHOPIFY_FLAG_PATH", "hasDynamicHelp": false, diff --git a/packages/eslint-plugin-cli/rules/json-output-command-exceptions.js b/packages/eslint-plugin-cli/rules/json-output-command-exceptions.js index efcff879951..4a9548c0158 100644 --- a/packages/eslint-plugin-cli/rules/json-output-command-exceptions.js +++ b/packages/eslint-plugin-cli/rules/json-output-command-exceptions.js @@ -3,7 +3,6 @@ const commandExceptions = [ // Existing finite commands awaiting migration. Remove entries as they adopt typed JSON output. // Do not add new finite commands to this section. 'packages/plugin-did-you-mean/src/commands/config/autocorrect/off.ts', - 'packages/plugin-did-you-mean/src/commands/config/autocorrect/on.ts', 'packages/theme/src/cli/commands/theme/check.ts', 'packages/theme/src/cli/commands/theme/init.ts', 'packages/theme/src/cli/commands/theme/metafields/pull.ts', diff --git a/packages/plugin-did-you-mean/src/commands/config/autocorrect/autocorrect.test.ts b/packages/plugin-did-you-mean/src/commands/config/autocorrect/autocorrect.test.ts index 96252e03966..76ea0aed797 100644 --- a/packages/plugin-did-you-mean/src/commands/config/autocorrect/autocorrect.test.ts +++ b/packages/plugin-did-you-mean/src/commands/config/autocorrect/autocorrect.test.ts @@ -1,4 +1,5 @@ import AutocorrectStatus from './status.js' +import AutocorrectOn from './on.js' import {isAutocorrectEnabled, setAutocorrect} from '../../../services/conf.js' import {autocorrectJsonOutputSchema} from '../../../services/autocorrect/types.js' import {launchCLI} from '@shopify/cli-kit/node/cli-launcher' @@ -19,7 +20,10 @@ afterEach(() => { vi.unstubAllEnvs() }) -const commands = [{name: 'status', command: AutocorrectStatus, enabled: false}] +const commands = [ + {name: 'status', command: AutocorrectStatus, enabled: false}, + {name: 'on', command: AutocorrectOn, enabled: true}, +] test.each(commands)('$name exposes the result schema and JSON flags in help', ({command}) => { expect(command.jsonOutputSchema).toBe(autocorrectJsonOutputSchema) diff --git a/packages/plugin-did-you-mean/src/commands/config/autocorrect/on.test.ts b/packages/plugin-did-you-mean/src/commands/config/autocorrect/on.test.ts index 59025187a8c..f295062e026 100644 --- a/packages/plugin-did-you-mean/src/commands/config/autocorrect/on.test.ts +++ b/packages/plugin-did-you-mean/src/commands/config/autocorrect/on.test.ts @@ -1,6 +1,5 @@ import AutocorrectOn from './on.js' import {setAutocorrect} from '../../../services/conf.js' -import {Config} from '@oclif/core' import {describe, expect, vi, test} from 'vitest' import {mockAndCaptureOutput} from '@shopify/cli-kit/node/testing/output' @@ -9,11 +8,10 @@ vi.mock('../../../services/conf.js') describe('AutocorrectOn', () => { test('Enables autocorrect config to on', async () => { // Given - const config = new Config({root: __dirname}) const outputMock = mockAndCaptureOutput() // When - await new AutocorrectOn([], config).run() + await AutocorrectOn.run([], import.meta.url) // Then expect(setAutocorrect).toBeCalledWith(true) diff --git a/packages/plugin-did-you-mean/src/commands/config/autocorrect/on.ts b/packages/plugin-did-you-mean/src/commands/config/autocorrect/on.ts index 98fad9cbee7..2bb8011569c 100644 --- a/packages/plugin-did-you-mean/src/commands/config/autocorrect/on.ts +++ b/packages/plugin-did-you-mean/src/commands/config/autocorrect/on.ts @@ -1,7 +1,8 @@ -import {autocorrectStatus} from '../../../services/constants.js' -import {setAutocorrect} from '../../../services/conf.js' +import {configureAutocorrect} from '../../../services/autocorrect/index.js' +import {presentAutocorrectResult} from '../../../services/autocorrect/result.js' +import {autocorrectJsonOutputSchema} from '../../../services/autocorrect/types.js' import Command from '@shopify/cli-kit/node/base-command' -import {renderInfo} from '@shopify/cli-kit/node/ui' +import {globalFlags, jsonFlag} from '@shopify/cli-kit/node/cli' export default class AutocorrectOn extends Command { static summary = 'Enable autocorrect. Off by default.' @@ -15,8 +16,18 @@ export default class AutocorrectOn extends Command { static description = this.descriptionForHelp() + static flags = { + ...globalFlags, + ...jsonFlag, + } + + static get jsonOutputSchema() { + return autocorrectJsonOutputSchema + } + async run(): Promise { - setAutocorrect(true) - renderInfo({body: autocorrectStatus.on}) + const {flags} = await this.parse(AutocorrectOn) + const result = configureAutocorrect(true) + presentAutocorrectResult(result, flags.json ? 'json' : 'text') } } diff --git a/packages/plugin-did-you-mean/src/services/autocorrect/index.test.ts b/packages/plugin-did-you-mean/src/services/autocorrect/index.test.ts index 3b166579c4d..3bb812acec5 100644 --- a/packages/plugin-did-you-mean/src/services/autocorrect/index.test.ts +++ b/packages/plugin-did-you-mean/src/services/autocorrect/index.test.ts @@ -1,4 +1,4 @@ -import {getAutocorrectStatus} from './index.js' +import {configureAutocorrect, getAutocorrectStatus} from './index.js' import * as conf from '../conf.js' import {inTemporaryDirectory} from '@shopify/cli-kit/node/fs' import {LocalStorage} from '@shopify/cli-kit/node/local-storage' @@ -27,3 +27,22 @@ test('returns the default and persisted preferences without changing configurati }) }) }) + +test('persists configured preferences and returns typed data without printing output', async () => { + await inTemporaryDirectory(async (directory) => { + const storage = new LocalStorage({cwd: directory}) + const {setAutocorrect} = conf + vi.spyOn(conf, 'setAutocorrect').mockImplementation((enabled) => setAutocorrect(enabled, storage)) + + await withCapturedStandardStreams(({stdout, stderr}) => { + for (const enabled of [true, false]) { + expect(configureAutocorrect(enabled)).toEqual({enabled}) + const reloadedStorage = new LocalStorage({cwd: directory}) + expect(reloadedStorage.get('autocorrectEnabled')).toBe(enabled) + } + + expect(stdout()).toBe('') + expect(stderr()).toBe('') + }) + }) +}) diff --git a/packages/plugin-did-you-mean/src/services/autocorrect/index.ts b/packages/plugin-did-you-mean/src/services/autocorrect/index.ts index 8905afb7a28..6637867897a 100644 --- a/packages/plugin-did-you-mean/src/services/autocorrect/index.ts +++ b/packages/plugin-did-you-mean/src/services/autocorrect/index.ts @@ -1,6 +1,11 @@ -import {isAutocorrectEnabled} from '../conf.js' +import {isAutocorrectEnabled, setAutocorrect} from '../conf.js' import type {AutocorrectResult} from './types.js' export function getAutocorrectStatus(): AutocorrectResult { return {enabled: isAutocorrectEnabled()} } + +export function configureAutocorrect(enabled: boolean): AutocorrectResult { + setAutocorrect(enabled) + return {enabled} +}