UNPKG

@dscodotco/theme-cli

Version:

A CLI tool for developing Shopify themes

100 lines (88 loc) 3.04 kB
import { createLogger } from "../logger.js"; import { ShopifyCredentials, ThemeManager } from "./theme-manager.js"; import Shopify from "shopify-api-node"; import fetch from "node-fetch"; import path from "path"; import fs from "fs"; import got from "got"; import crypto from "crypto"; const logger = createLogger("shopify-renderer"); export interface RendererOptions { credentials: ShopifyCredentials; themeId: number; shopify: Shopify; } /** * A service for rendering Shopify Liquid templates * using Shopify's own rendering engine via the Admin API */ export class ShopifyRenderer { private credentials: ShopifyCredentials; private themeId: number; private shopify: Shopify; private baseUrl: string; /** * Creates a new ShopifyRenderer instance * @param options Renderer configuration options */ constructor(options: RendererOptions) { this.credentials = options.credentials; this.themeId = options.themeId; this.shopify = options.shopify; this.baseUrl = `https://${options.credentials.storeName}.myshopify.com`; } /** * Renders a template by uploading it to Shopify and fetching the rendered content */ async renderTemplate(content: string): Promise<string> { // Generate a unique key for this template const key = `templates/${crypto.randomBytes(6).toString("hex")}.liquid`; // Log debug info logger.info("=== Debug Info ==="); logger.info(`Template Key: ${key}`); logger.info(`Template Content: ${content}`); logger.info(`Theme ID: ${this.themeId}`); logger.info(`Store URL: ${this.baseUrl}`); try { // Step 1: Create a temporary asset with our template logger.info("Step 1: Creating temporary asset"); await this.shopify.asset.create(this.themeId, { key, value: content, }); logger.info("✓ Asset created successfully"); // Step 2: Fetch the rendered content logger.info( `Step 2: Fetching from URL: ${this.baseUrl}/?view=${key.split(".")[1]}` ); const response = await got(`${this.baseUrl}/?view=${key.split(".")[1]}`, { headers: { "X-Shopify-Access-Token": this.credentials.password, }, }); logger.info("✓ Content fetched successfully"); logger.info(`Response length: ${response.body.length} characters`); // Step 3: Clean up the temporary asset logger.info("Step 3: Cleaning up temporary asset"); try { await this.shopify.asset.delete(this.themeId, key); logger.info("✓ Asset deleted successfully"); } catch (error) { logger.error("✗ Asset deletion failed:"); logger.error(error); } return response.body; } catch (error) { logger.error("✗ Template rendering failed:"); logger.error(error); throw error; } } /** * Gets the URL for previewing the current template * @returns The preview URL */ getPreviewUrl(): string { return `${this.baseUrl}?preview_theme_id=${this.themeId}`; } }