From 8fb6e86995c37ac2a785873c1bdf371517d7080a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20G=C3=B6kdemir?= Date: Sat, 3 Oct 2026 15:17:17 +0300 Subject: [PATCH] fix(vscode): avoid automatic Shopify login prompts --- .changeset/bright-tools-listen.md | 5 +++ .../src/server/Configuration.ts | 12 ++++++ .../src/server/startServer.spec.ts | 43 ++++++++++++++++++- .../src/server/startServer.ts | 7 ++- packages/vscode-extension/README.md | 1 + packages/vscode-extension/package.json | 7 +++ 6 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 .changeset/bright-tools-listen.md diff --git a/.changeset/bright-tools-listen.md b/.changeset/bright-tools-listen.md new file mode 100644 index 000000000..d1852a4d4 --- /dev/null +++ b/.changeset/bright-tools-listen.md @@ -0,0 +1,5 @@ +--- +'@shopify/theme-language-server-common': patch +--- + +Make automatic Shopify metafield fetching opt-in so opening a theme workspace does not unexpectedly start CLI authentication. diff --git a/packages/theme-language-server-common/src/server/Configuration.ts b/packages/theme-language-server-common/src/server/Configuration.ts index dd4fc90b6..db3c5647c 100644 --- a/packages/theme-language-server-common/src/server/Configuration.ts +++ b/packages/theme-language-server-common/src/server/Configuration.ts @@ -11,11 +11,13 @@ export const CHECK_ON_OPEN = 'themeCheck.checkOnOpen' as const; export const CHECK_ON_SAVE = 'themeCheck.checkOnSave' as const; export const CHECK_ON_CHANGE = 'themeCheck.checkOnChange' as const; export const PRELOAD_ON_BOOT = 'themeCheck.preloadOnBoot' as const; +export const FETCH_METAFIELD_DEFINITIONS = 'themeCheck.fetchMetafieldDefinitions' as const; export const ConfigurationKeys = [ CHECK_ON_OPEN, CHECK_ON_SAVE, CHECK_ON_CHANGE, PRELOAD_ON_BOOT, + FETCH_METAFIELD_DEFINITIONS, ] as const; export class Configuration { @@ -23,6 +25,7 @@ export class Configuration { [CHECK_ON_SAVE]: boolean = true; [CHECK_ON_CHANGE]: boolean = true; [PRELOAD_ON_BOOT]: boolean = true; + [FETCH_METAFIELD_DEFINITIONS]: boolean = false; constructor( private connection: Connection, @@ -37,6 +40,10 @@ export class Configuration { this[CHECK_ON_SAVE] = this.capabilities.initializationOption(CHECK_ON_SAVE, true); this[CHECK_ON_CHANGE] = this.capabilities.initializationOption(CHECK_ON_CHANGE, true); this[PRELOAD_ON_BOOT] = this.capabilities.initializationOption(PRELOAD_ON_BOOT, true); + this[FETCH_METAFIELD_DEFINITIONS] = this.capabilities.initializationOption( + FETCH_METAFIELD_DEFINITIONS, + false, + ); } async shouldCheckOnOpen() { @@ -59,6 +66,11 @@ export class Configuration { return this[PRELOAD_ON_BOOT]; } + async shouldFetchMetafieldDefinitions() { + await this.fetchConfiguration(); + return this[FETCH_METAFIELD_DEFINITIONS]; + } + clearCache() { this.fetchConfiguration.clearCache(); } diff --git a/packages/theme-language-server-common/src/server/startServer.spec.ts b/packages/theme-language-server-common/src/server/startServer.spec.ts index 5f0bf8acb..2dc91e4a7 100644 --- a/packages/theme-language-server-common/src/server/startServer.spec.ts +++ b/packages/theme-language-server-common/src/server/startServer.spec.ts @@ -10,7 +10,12 @@ import { } from 'vscode-languageserver'; import { MockConnection, mockConnection } from '../test/MockConnection'; import { Dependencies } from '../types'; -import { CHECK_ON_CHANGE, CHECK_ON_OPEN, CHECK_ON_SAVE } from './Configuration'; +import { + CHECK_ON_CHANGE, + CHECK_ON_OPEN, + CHECK_ON_SAVE, + FETCH_METAFIELD_DEFINITIONS, +} from './Configuration'; import { startServer } from './startServer'; const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); @@ -23,13 +28,15 @@ describe('Module: server', () => { let checkOnChange: boolean | null = null; let checkOnSave: boolean | null = null; let checkOnOpen: boolean | null = null; + let fetchMetafieldDefinitionsSetting: boolean | null = null; let connection: MockConnection; let dependencies: ReturnType; let fileTree: MockTheme; let logger: any; + let fetchMetafieldDefinitionsForURI: ReturnType; beforeEach(() => { - checkOnChange = checkOnSave = checkOnOpen = null; + checkOnChange = checkOnSave = checkOnOpen = fetchMetafieldDefinitionsSetting = null; // Initialize all ze mocks... connection = mockConnection(mockRoot); @@ -45,12 +52,16 @@ describe('Module: server', () => { return checkOnOpen; case CHECK_ON_SAVE: return checkOnSave; + case FETCH_METAFIELD_DEFINITIONS: + return fetchMetafieldDefinitionsSetting; default: return null; } }); } else if (method === 'client/registerCapability') { return null; + } else if (method === 'workspace/workspaceFolders') { + return [{ uri: mockRoot, name: 'theme' }]; } else { throw new Error( `Does not know how to mock response to '${method}' requests. Check your test.`, @@ -60,7 +71,9 @@ describe('Module: server', () => { fileTree = { '.theme-check.yml': '', 'snippets/code.liquid': fileContents }; logger = vi.fn(); + fetchMetafieldDefinitionsForURI = vi.fn(); dependencies = getDependencies(logger, fileTree); + dependencies.fetchMetafieldDefinitionsForURI = fetchMetafieldDefinitionsForURI; // Start the server startServer(connection, dependencies); @@ -79,6 +92,31 @@ describe('Module: server', () => { expect(logger).toHaveBeenCalledWith("[SERVER] Let's roll!"); }); + it('does not fetch metafield definitions by default', async () => { + connection.setup({ + workspace: { + configuration: true, + workspaceFolders: { supported: true }, + }, + }); + await flushAsync(); + + expect(fetchMetafieldDefinitionsForURI).not.toHaveBeenCalled(); + }); + + it('fetches metafield definitions when enabled', async () => { + fetchMetafieldDefinitionsSetting = true; + connection.setup({ + workspace: { + configuration: true, + workspaceFolders: { supported: true }, + }, + }); + await flushAsync(); + + expect(fetchMetafieldDefinitionsForURI).toHaveBeenCalledWith(mockRoot); + }); + it('should debounce calls to runChecks', async () => { connection.setup(); await flushAsync(); @@ -392,6 +430,7 @@ describe('Module: server', () => { jsonValidationSet: { schemas: async () => [], }, + fetchMetafieldDefinitionsForURI, }; } diff --git a/packages/theme-language-server-common/src/server/startServer.ts b/packages/theme-language-server-common/src/server/startServer.ts index 00026e797..54afc4b9b 100644 --- a/packages/theme-language-server-common/src/server/startServer.ts +++ b/packages/theme-language-server-common/src/server/startServer.ts @@ -366,7 +366,12 @@ export function startServer( ); const fetchMetafieldDefinitionsForWorkspaceFolders = async (folders: WorkspaceFolder[]) => { - if (!fetchMetafieldDefinitionsForURI) return; + if ( + !fetchMetafieldDefinitionsForURI || + !(await configuration.shouldFetchMetafieldDefinitions()) + ) { + return; + } for (let folder of folders) { const mode = await getModeForURI(folder.uri); diff --git a/packages/vscode-extension/README.md b/packages/vscode-extension/README.md index 5ca90a81f..a5ed93090 100644 --- a/packages/vscode-extension/README.md +++ b/packages/vscode-extension/README.md @@ -41,6 +41,7 @@ This VS Code extensions comes with batteries included. - `"themeCheck.checkOnChange": boolean`, (default: `true`) makes it so theme check runs on file change. - `"themeCheck.checkOnSave": boolean`, (default: `true`) makes it so theme check runs on file save. - `"themeCheck.preloadOnBoot": boolean`, (default: `true`) makes it so all files are preloaded on extension activation. +- `"themeCheck.fetchMetafieldDefinitions": boolean`, (default: `false`) fetches metafield definitions from Shopify when a theme workspace is opened. This may prompt you to log in to Shopify. ## License diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index 8cf4af661..cfaa17314 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -165,6 +165,13 @@ ], "description": "When true, theme check preloads all the files from your theme for fast rename handling and theme graph generation.", "default": true + }, + "themeCheck.fetchMetafieldDefinitions": { + "type": [ + "boolean" + ], + "description": "When true, fetches metafield definitions from Shopify when a theme workspace is opened. This may prompt you to log in to Shopify.", + "default": false } } },