diff --git a/packages/theme/src/cli/utilities/theme-selector/fetch.test.ts b/packages/theme/src/cli/utilities/theme-selector/fetch.test.ts index 9cd6058942d..30c3b5a831b 100644 --- a/packages/theme/src/cli/utilities/theme-selector/fetch.test.ts +++ b/packages/theme/src/cli/utilities/theme-selector/fetch.test.ts @@ -1,12 +1,33 @@ -import {fetchStoreThemes} from './fetch.js' +import {fetchStoreThemes, publicFetchStoreThemes} from './fetch.js' import {fetchThemes} from '@shopify/cli-kit/node/themes/api' import {Theme} from '@shopify/cli-kit/node/themes/types' import {test, vi, describe, expect} from 'vitest' import {AbortError} from '@shopify/cli-kit/node/error' +import {ensureAuthenticatedThemes} from '@shopify/cli-kit/node/session' const session = {token: 'token', storeFqdn: 'my-shop.myshopify.com'} vi.mock('@shopify/cli-kit/node/themes/api') +vi.mock('@shopify/cli-kit/node/session') + +// This function serves as a wrapper around fetchStoreThemes +// which allows library users to pass a password to authenticate with the Theme API. +describe('publicFetchStoreThemes', () => { + test('authenticates and fetches themes', async () => { + // Given + const store = 'my-store' + const password = 'password123' + vi.mocked(ensureAuthenticatedThemes).mockResolvedValue(session) + vi.mocked(fetchThemes).mockResolvedValue([theme(1, 'unpublished'), theme(2, 'live'), theme(3, 'unpublished')]) + + // When + await publicFetchStoreThemes(store, password) + + // Then + expect(ensureAuthenticatedThemes).toHaveBeenCalledWith(store, password) + expect(fetchThemes).toHaveBeenCalledWith(session) + }) +}) describe('fetchStoreThemes', () => { test('returns only allowed themes', async () => { diff --git a/packages/theme/src/cli/utilities/theme-selector/fetch.ts b/packages/theme/src/cli/utilities/theme-selector/fetch.ts index 857d4fd8f7c..0ec4dbee22d 100644 --- a/packages/theme/src/cli/utilities/theme-selector/fetch.ts +++ b/packages/theme/src/cli/utilities/theme-selector/fetch.ts @@ -1,11 +1,22 @@ import {fetchThemes} from '@shopify/cli-kit/node/themes/api' -import {AdminSession} from '@shopify/cli-kit/node/session' +import {AdminSession, ensureAuthenticatedThemes} from '@shopify/cli-kit/node/session' import {AbortError} from '@shopify/cli-kit/node/error' import {Theme} from '@shopify/cli-kit/node/themes/types' export type Role = 'live' | 'development' | 'unpublished' export const ALLOWED_ROLES: Role[] = ['live', 'unpublished', 'development'] +/** + * Fetches the themes from the store. + * @param store - Store URL. It can be the store prefix (example) or the full myshopify.com URL (example.myshopify.com, https://example.myshopify.com). + * @param password - Password generated from the Theme Access app. + * @returns An array of themes from the store. + */ +export async function publicFetchStoreThemes(store: string, password: string) { + const adminSession = await ensureAuthenticatedThemes(store, password) + return fetchStoreThemes(adminSession) +} + export async function fetchStoreThemes(session: AdminSession) { const store = session.storeFqdn const themes = (await fetchThemes(session)).filter(isRoleAllowed) diff --git a/packages/theme/src/index.ts b/packages/theme/src/index.ts index 5c391d93713..b5453c98cab 100644 --- a/packages/theme/src/index.ts +++ b/packages/theme/src/index.ts @@ -16,6 +16,7 @@ import Serve from './cli/commands/theme/serve.js' import Share from './cli/commands/theme/share.js' import {pull} from './cli/services/pull.js' import {push} from './cli/services/push.js' +import {publicFetchStoreThemes} from './cli/utilities/theme-selector/fetch.js' const COMMANDS = { 'theme:init': Init, @@ -39,6 +40,7 @@ const COMMANDS = { const PUBLIC_COMMANDS = { pull, push, + publicFetchStoreThemes, } export {PUBLIC_COMMANDS}