UNPKG

@dscodotco/theme-cli

Version:

A CLI tool for developing Shopify themes

102 lines (101 loc) 3.52 kB
import axios from "axios"; import { createLogger } from "../logger.js"; const logger = createLogger("theme-manager"); /** * Manages Shopify themes through the Admin API */ export class ThemeManager { /** * Creates a new ThemeManager instance * @param credentials Shopify store credentials */ constructor(credentials) { /** * Gets the appropriate authentication configuration for Shopify API calls * @returns Authentication config object */ this.getAuthConfig = () => { if (this.isAccessToken) { // Access token auth - use headers return { headers: { "X-Shopify-Access-Token": this.credentials.password, "Content-Type": "application/json", }, }; } else { // API key + secret auth - use basic auth return { auth: { username: this.credentials.apiKey, password: this.credentials.password, }, headers: { "Content-Type": "application/json", }, }; } }; this.credentials = credentials; this.baseUrl = `https://${credentials.storeName}.myshopify.com`; this.apiUrl = `${this.baseUrl}/admin/api/2023-04`; // Determine if we're using an access token (shpat_) or API key + secret this.isAccessToken = this.credentials.password.startsWith("shpat_"); if (!this.isAccessToken) { logger.info("Using API key + secret authentication"); } else { logger.info("Using access token authentication"); } } /** * Lists all themes in the store * @returns Promise containing array of themes */ async listThemes() { try { const authConfig = this.getAuthConfig(); const response = await axios.get(`${this.apiUrl}/themes.json`, authConfig); return response.data.themes; } catch (error) { logger.error(`Failed to list themes: ${error.message}`); throw error; } } /** * Creates a new development theme * @param name The name for the new theme * @returns The created theme */ async createDevelopmentTheme(name) { const themeName = name || `Development Theme (${new Date().toISOString()})`; const requestBody = { theme: { name: themeName, role: "development", }, }; try { logger.info(`Creating new development theme: ${themeName}`); const authConfig = this.getAuthConfig(); const response = await axios.post(`${this.apiUrl}/themes.json`, requestBody, authConfig); const newTheme = response.data.theme; logger.success(`Created new development theme: ${newTheme.name} (ID: ${newTheme.id})`); return newTheme; } catch (error) { logger.error(`Failed to create development theme: ${error.message}`); throw error; } } /** * Gets the preview URL for a theme * @param themeId The theme ID * @returns The preview URL */ getThemePreviewUrl(themeId) { return `${this.baseUrl}/?preview_theme_id=${themeId}`; } }