### Shop Client Quick Start: Initialize and Fetch Data Source: https://github.com/peppyhop/shop-client/blob/main/README.md A basic example demonstrating how to initialize the ShopClient and fetch store information, all products, or a specific product. This serves as a starting point for using the library. ```typescript import { ShopClient } from 'shop-client'; // Initialize shop client instance const shop = new ShopClient("your-store-domain.com"); // Fetch store information const storeInfo = await shop.getInfo(); // Fetch all products const products = await shop.products.all(); // Find specific product const product = await shop.products.find("product-handle"); ``` -------------------------------- ### Start Development Server Source: https://github.com/peppyhop/shop-client/blob/main/CONTRIBUTING.md Command to start the development server for the shop-client project. This typically enables features like hot-reloading for a smoother development experience. ```bash npm run dev ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/peppyhop/shop-client/blob/main/CONTRIBUTING.md Command to install all necessary dependencies for the shop-client project using npm. This should be run after cloning the repository. ```bash npm install ``` -------------------------------- ### Install Shop Client with npm, yarn, or pnpm Source: https://github.com/peppyhop/shop-client/blob/main/README.md Instructions for installing the shop-client library using different package managers. This is the first step to integrating the library into your project. ```bash npm install shop-client ``` ```bash yarn add shop-client ``` ```bash pnpm add shop-client ``` -------------------------------- ### TypeScript Basic Shop Client Usage Source: https://github.com/peppyhop/shop-client/blob/main/llm.txt Demonstrates the basic usage of the ShopClient library in TypeScript. It shows how to instantiate the client with a store domain and then fetch all products and store information using the respective methods. This serves as a starting point for integrating the library. ```typescript import { ShopClient } from 'shop-client'; const shop = new ShopClient('store-domain.com'); const products = await shop.products.all(); const storeInfo = await shop.getInfo(); ``` -------------------------------- ### Initialize ShopClient and Configure Rate Limiting (TypeScript) Source: https://context7.com/peppyhop/shop-client/llms.txt Demonstrates how to initialize the ShopClient with different configurations, including basic setup, custom cache TTL, and AI features. It also shows how to globally configure rate limiting for the client. ```typescript import { ShopClient, configureRateLimit } from 'shop-client'; // Basic initialization const shop = new ShopClient('https://example-store.com'); // With custom cache TTL (10 seconds) const shopWithCache = new ShopClient('https://example-store.com', { cacheTTL: 10_000, }); // With OpenRouter AI configuration for enrichment features const shopWithAI = new ShopClient('https://example-store.com', { openRouter: { apiKey: 'YOUR_OPENROUTER_API_KEY', model: 'openai/gpt-4o-mini', }, }); // Configure global rate limiting (optional, recommended for crawling) configureRateLimit({ enabled: true, maxRequestsPerInterval: 10, intervalMs: 1000, maxConcurrency: 3, }); ``` -------------------------------- ### Jest Unit Testing for Product Operations in TypeScript Source: https://github.com/peppyhop/shop-client/blob/main/CONTRIBUTING.md An example of a unit test suite for a `ProductOperations` class using Jest. It demonstrates setting up mocks for `fetch`, testing successful API responses, and handling network errors. ```typescript // Example test structure describe('ProductOperations', () => { let mockFetch: jest.MockedFunction; let operations: ProductOperations; beforeEach(() => { mockFetch = jest.fn(); global.fetch = mockFetch; operations = new ProductOperations('test.myshopify.com'); }); afterEach(() => { jest.resetAllMocks(); }); describe('all()', () => { it('should return products when API responds successfully', async () => { const mockProducts = [ { id: 1, title: 'Test Product', handle: 'test-product' } ]; mockFetch.mockResolvedValueOnce({ ok: true, json: async () => ({ products: mockProducts }) } as Response); const result = await operations.all(); expect(result).toEqual(mockProducts); expect(mockFetch).toHaveBeenCalledWith( 'https://test.myshopify.com/products.json' ); }); it('should return null when API fails', async () => { mockFetch.mockRejectedValueOnce(new Error('Network error')); const result = await operations.all(); expect(result).toBeNull(); }); }); }); ``` -------------------------------- ### Fetch All Products with Pagination and Options (TypeScript) Source: https://context7.com/peppyhop/shop-client/llms.txt Illustrates how to fetch all products from a Shopify store using the products.all() method. It covers fetching minimal product data by default and requesting full product details, including images and options. The example also shows how to specify a currency override. ```typescript import { ShopClient } from 'shop-client'; const shop = new ShopClient('https://example-store.com'); // Fetch all products with minimal payload (default) const minimalProducts = await shop.products.all(); console.log(`Found ${minimalProducts?.length} products`); // Minimal product fields: title, price, compareAtPrice, discount, images, // featuredImage, available, productType, localizedPricing, options, url, slug, platformId // Fetch all products with full payload const fullProducts = await shop.products.all({ columns: { mode: 'full', images: 'full', options: 'full' }, }); // Full product includes: handle, vendor, tags, bodyHtml, variants, // priceMin, priceMax, currency, createdAt, updatedAt, publishedAt, etc. if (fullProducts && fullProducts.length > 0) { const product = fullProducts[0]; console.log(product.title); // "Summer Dress" console.log(product.handle); // "summer-dress" console.log(product.price); // 2500 (in cents) console.log(product.available); // true console.log(product.vendor); // "Acme Brand" console.log(product.variants?.length); // 5 } // With currency override const productsInEUR = await shop.products.all({ currency: 'EUR' }); ``` -------------------------------- ### GET /products/all Source: https://github.com/peppyhop/shop-client/blob/main/README.md Fetches all products from the store with automatic pagination handling. Gift cards are excluded. ```APIDOC ## GET /products/all ### Description Fetches all products from the store with automatic pagination handling. Gift cards are excluded. ### Method `GET` ### Endpoint `/products/all` ### Parameters None ### Request Example ```typescript const allProducts = await shop.products.all(); ``` ### Response #### Success Response (200) - Returns an array of `ProductResult` objects or `null`. #### Response Example ```json [ { "id": "product-id-1", "name": "Example Product 1", "price": { "amount": "19.99", "currencyCode": "USD" } }, { "id": "product-id-2", "name": "Example Product 2", "price": { "amount": "29.99", "currencyCode": "USD" } } ] ``` ### Notes - Gift cards are excluded from product responses. Any product whose `product_type` / `type` contains `"gift card"` will be skipped. ``` -------------------------------- ### Fetch Store Information using getInfo() (TypeScript) Source: https://context7.com/peppyhop/shop-client/llms.txt Shows how to retrieve comprehensive metadata about a Shopify store using the getInfo() method. This includes branding, social links, contact details, and featured content. The example also demonstrates how to force a refresh to bypass the cache. ```typescript import { ShopClient } from 'shop-client'; const shop = new ShopClient('https://anuki.in'); const storeInfo = await shop.getInfo(); console.log(storeInfo.name); // "Anuki" console.log(storeInfo.domain); // "https://anuki.in/" console.log(storeInfo.slug); // "anuki" console.log(storeInfo.title); // Store title from meta tags console.log(storeInfo.description); // Store description console.log(storeInfo.logoUrl); // Store logo URL console.log(storeInfo.country); // "IN" (ISO 3166-1 alpha-2) console.log(storeInfo.currency); // "INR" (ISO 4217) // Social links console.log(storeInfo.socialLinks.instagram); // "https://instagram.com/anuki" console.log(storeInfo.socialLinks.facebook); // Facebook URL if available // Contact information console.log(storeInfo.contactLinks.email); // "contact@anuki.in" console.log(storeInfo.contactLinks.tel); // Phone number console.log(storeInfo.contactLinks.contactPage); // "/pages/contact" // Featured content from homepage console.log(storeInfo.showcase.products); // ["product-handle-1", "product-handle-2"] console.log(storeInfo.showcase.collections); // ["collection-handle-1"] // Force refresh (bypass cache) const freshInfo = await shop.getInfo({ force: true }); ``` -------------------------------- ### GET /store/info Source: https://github.com/peppyhop/shop-client/blob/main/README.md Fetches comprehensive store metadata including branding, social links, and featured content. ```APIDOC ## GET /store/info ### Description Fetches comprehensive store metadata including branding, social links, and featured content. ### Method `GET` ### Endpoint `/store/info` ### Parameters None ### Request Example ```typescript const storeInfo = await shop.getInfo(); ``` ### Response #### Success Response (200) - **name** (string) - Store name from meta tags. - **title** (string) - Store title. - **description** (string) - Store description. - **domain** (string) - Store domain. - **slug** (string) - Generated store slug. - **logoUrl** (string) - Store logo URL. - **socialLinks** (object) - Social media URLs (Facebook, Instagram, etc.). - **contactLinks** (object) - Contact information (phone, email, contact page). - **headerLinks** (array) - Navigation menu links. - **showcase** (object) - Featured products and collections. - **jsonLdData** (object) - Structured data from the store. - **country** (string) - ISO 3166-1 alpha-2 code (e.g., `US`, `GB`). - **currency** (string) - ISO 4217 currency code (e.g., `USD`, `EUR`). #### Response Example ```json { "name": "Example Store", "title": "Your Online Shopping Destination", "description": "Find the best products and deals.", "domain": "example-store.com", "slug": "example-store", "logoUrl": "https://example.com/logo.png", "socialLinks": { "facebook": "https://facebook.com/example", "instagram": "https://instagram.com/example" }, "contactLinks": { "phone": "123-456-7890", "email": "contact@example.com" }, "headerLinks": [ { "text": "Home", "url": "/" }, { "text": "Products", "url": "/products" } ], "showcase": { "featuredProducts": ["product-id-1", "product-id-2"], "featuredCollections": ["collection-id-1"] }, "jsonLdData": {}, "country": "US", "currency": "USD" } ``` ``` -------------------------------- ### TypeScript Advanced Product Filtering Example Source: https://github.com/peppyhop/shop-client/blob/main/llm.txt Illustrates how to retrieve available filter options for products using the ShopClient library. The `products.filter()` method returns an object containing filterable attributes and their possible values, such as sizes and colors. This is useful for implementing dynamic product filtering UIs. ```typescript const filters = await shop.products.filter(); // Returns: { "size": ["s", "m", "l"], "color": ["red", "blue"] } ``` -------------------------------- ### Get Product Filters - products.filter() Source: https://context7.com/peppyhop/shop-client/llms.txt Creates a map of all variant options and their distinct values from the entire product catalog. This is useful for building filter UIs. It requires an initialized ShopClient instance. ```typescript import { ShopClient } from 'shop-client'; const shop = new ShopClient('https://example-store.com'); const filters = await shop.products.filter(); console.log('Available filters:', filters); // Output: { // "size": ["s", "m", "l", "xl"], // "color": ["black", "blue", "red", "white"], // "material": ["cotton", "polyester"] // } // Build filter UI if (filters) { Object.entries(filters).forEach(([optionName, values]) => { console.log(`${optionName}: ${values.join(', ')}`); }); } ``` -------------------------------- ### Get Collection Products - collections.products Source: https://context7.com/peppyhop/shop-client/llms.txt Fetches products from a specific collection with pagination support. It requires an initialized ShopClient instance, a collection handle, and optional parameters for pagination and product details. Can retrieve all products, paginated products, product slugs, or full product details. ```typescript import { ShopClient } from 'shop-client'; const shop = new ShopClient('https://example-store.com'); // All products from a collection const allProducts = await shop.collections.products.all('summer-collection'); console.log(`${allProducts?.length} products in collection`); // Paginated products from collection const page1 = await shop.collections.products.paginated('summer-collection', { page: 1, limit: 24, currency: 'EUR', }); // With full product details const fullProducts = await shop.collections.products.all('summer-collection', { columns: { mode: 'full', images: 'full', options: 'full' }, currency: 'USD', }); // Get only product slugs (lightweight) const slugs = await shop.collections.products.slugs('summer-collection'); console.log('Product slugs:', slugs); ``` -------------------------------- ### TypeScript Strict Type Safety Example Source: https://github.com/peppyhop/shop-client/blob/main/CONTRIBUTING.md Demonstrates the importance of strict type safety in TypeScript, including explicit type definitions and proper null handling. It shows a good and a bad example of a function signature and implementation. ```typescript // ✅ Good - Explicit types and null handling async function getProduct(handle: string): Promise { try { const response = await fetch(`/products/${handle}.json`); if (!response.ok) return null; return await response.json(); } catch { return null; } } // ❌ Bad - Any types and missing error handling async function getProduct(handle: any): Promise { const response = await fetch(`/products/${handle}.json`); return response.json(); } ``` -------------------------------- ### Bug Report Reproduction Steps Source: https://github.com/peppyhop/shop-client/blob/main/CONTRIBUTING.md Illustrates the steps to reproduce a bug report, including initializing a client and calling a product retrieval method. This helps in identifying and fixing issues by providing a clear sequence of actions. ```markdown ```markdown 1. Initialize client with domain 'example.myshopify.com' 2. Call `client.products.all()` 3. Observe error in console ``` ``` -------------------------------- ### Server/Edge API Endpoint Source: https://github.com/peppyhop/shop-client/blob/main/README.md An example of an API endpoint (e.g., for Edge/Node.js) that uses shop-client to fetch shop information and return it as JSON. ```typescript // /api/shop-info.ts (Edge/Node) import { ShopClient } from 'shop-client'; export default async function handler(req, res) { const shop = new ShopClient('https://example.myshopify.com/'); const info = await shop.getInfo(); res.json(info); } ``` -------------------------------- ### Build and Upload Release Artifacts Source: https://github.com/peppyhop/shop-client/blob/main/RELEASE_GUIDE.md Builds the project, archives the distribution files into a tarball, and uploads it as a release artifact to GitHub. This step is optional and requires 'bun' and 'gh' CLI. ```bash bun run build tar -czf dist-vX.Y.Z.tgz dist/ gh release upload vX.Y.Z dist-vX.Y.Z.tgz --clobber ``` -------------------------------- ### GET /products/paginated Source: https://github.com/peppyhop/shop-client/blob/main/README.md Fetches products with manual pagination control, allowing for specific page and limit settings, and optional currency override. ```APIDOC ## GET /products/paginated ### Description Fetches products with manual pagination control, allowing for specific page and limit settings, and optional currency override. ### Method `GET` ### Endpoint `/products/paginated` ### Parameters #### Query Parameters - **page** (number) - Optional - Page number (default: 1). - **limit** (number) - Optional - Products per page (default: 250, max: 250). - **currency** (CurrencyCode) - Optional - ISO 4217 code aligned with `Intl.NumberFormatOptions['currency']` (e.g., `"USD"`, `"EUR"`, `"JPY"`). ### Request Example ```typescript const products = await shop.products.paginated({ page: 1, limit: 25, currency: "EUR", }); ``` ### Response #### Success Response (200) - Returns an array of `ProductResult` objects or `null`. #### Response Example ```json [ { "id": "product-id-1", "name": "Example Product 1", "price": { "amount": "19.99", "currencyCode": "EUR" } }, { "id": "product-id-2", "name": "Example Product 2", "price": { "amount": "29.99", "currencyCode": "EUR" } } ] ``` ### Notes - Gift cards are excluded from product responses. Any product whose `product_type` / `type` contains `"gift card"` will be skipped. ``` -------------------------------- ### Clone Shop Client Repository Source: https://github.com/peppyhop/shop-client/blob/main/CONTRIBUTING.md Instructions to clone the shop-client repository from GitHub. This is the initial step for any developer wanting to contribute to the project. ```bash git clone https://github.com/your-username/shop-client.git cd shop-client ``` -------------------------------- ### ShopClient Initialization and Store Info Retrieval (TypeScript) Source: https://github.com/peppyhop/shop-client/blob/main/ARCHITECTURE.md Demonstrates the basic structure of the ShopClient class, including its constructor for initialization and the getInfo method for fetching store metadata. It highlights the instantiation of operation classes and the primary entry point for store information. ```typescript class ShopClient { private domain: string; public products: ProductOperations; public collections: CollectionOperations; public checkout: CheckoutOperations; constructor(domain: string) { // Initialize domain and operation classes } async getInfo(): Promise { // Fetch store metadata } } ``` -------------------------------- ### Migration from Barrel to Subpath Imports (TypeScript) Source: https://github.com/peppyhop/shop-client/blob/main/README.md Provides TypeScript examples for migrating from barrel imports to deep subpath imports in shop-client for better tree-shaking. ```typescript // Before (barrel import) import { ShopClient, configureRateLimit } from 'shop-client'; // After (deep imports for better tree-shaking) import { ShopClient } from 'shop-client'; import { configureRateLimit } from 'shop-client/rate-limit'; // Feature-specific imports import { fetchProducts } from 'shop-client/products'; import { createCheckoutOperations } from 'shop-client/checkout'; ``` -------------------------------- ### Migration from Barrel to Subpath Imports (CommonJS) Source: https://github.com/peppyhop/shop-client/blob/main/README.md Shows CommonJS examples for migrating from barrel imports to deep subpath imports in shop-client, optimizing bundle size. ```javascript // Before const { ShopClient, configureRateLimit } = require('shop-client'); // After const { ShopClient } = require('shop-client'); const { configureRateLimit } = require('shop-client/rate-limit'); ``` -------------------------------- ### TypeScript Fetching Products from a Collection Source: https://github.com/peppyhop/shop-client/blob/main/llm.txt Shows how to fetch all products associated with a specific collection using its handle. The `collections.products.all(handle)` method allows developers to retrieve product data for a given collection, enabling the display of collection-specific items. ```typescript const collectionProducts = await shop.collections.products.all('collection-handle'); ``` -------------------------------- ### ShopClient Initialization Source: https://context7.com/peppyhop/shop-client/llms.txt Initializes the ShopClient for interacting with a Shopify store. Supports configuration for caching, rate limiting, and AI features. ```APIDOC ## ShopClient Initialization ### Description The main entry point for interacting with any Shopify store. Creates a client instance with optional configuration for caching, rate limiting, and AI features. ### Method `new ShopClient(storeUrl: string, options?: ShopClientOptions)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript import { ShopClient, configureRateLimit } from 'shop-client'; // Basic initialization const shop = new ShopClient('https://example-store.com'); // With custom cache TTL (10 seconds) const shopWithCache = new ShopClient('https://example-store.com', { cacheTTL: 10_000, }); // With OpenRouter AI configuration for enrichment features const shopWithAI = new ShopClient('https://example-store.com', { openRouter: { apiKey: 'YOUR_OPENROUTER_API_KEY', model: 'openai/gpt-4o-mini', }, }); // Configure global rate limiting (optional, recommended for crawling) configureRateLimit({ enabled: true, maxRequestsPerInterval: 10, intervalMs: 1000, maxConcurrency: 3, }); ``` ### Response #### Success Response (200) Returns an instance of `ShopClient`. #### Response Example ```json // No direct JSON response, returns a ShopClient instance ``` ``` -------------------------------- ### Manually Invalidate Shop Client Cache Source: https://github.com/peppyhop/shop-client/blob/main/README.md Shows how to manually clear the store info cache for the ShopClient. This is useful for proactively refreshing data, for example, after a content update on the Shopify store. ```typescript import { ShopClient } from "shop-client"; const shop = new ShopClient("https://exampleshop.com", { cacheTTL: 60_000 }); // Fetch and cache await shop.getInfo(); // Invalidate cache proactively (e.g., after a content update) shop.clearInfoCache(); // Next call refetches and repopulates cache await shop.getInfo(); ``` -------------------------------- ### Data Transformer Interface and Implementation (TypeScript) Source: https://github.com/peppyhop/shop-client/blob/main/ARCHITECTURE.md Defines a generic 'DataTransformer' interface with 'transform' and 'validate' methods. An example implementation, 'ProductTransformer', shows how to transform raw product data into the defined Product type. ```typescript interface DataTransformer { transform(input: T): U; validate(input: T): boolean; } class ProductTransformer implements DataTransformer { transform(raw: RawProduct): Product { // Custom transformation logic } } ``` -------------------------------- ### TypeScript: Bug Report Code Sample Source: https://github.com/peppyhop/shop-client/blob/main/CONTRIBUTING.md Provides a TypeScript code snippet demonstrating a potential bug scenario. It shows the initialization of a ShopClient and a call to `client.products.all()` which is expected to fail, useful for debugging and issue reporting. ```typescript ```typescript const client = new ShopClient('example.myshopify.com'); const products = await client.products.all(); // Fails here ``` ``` -------------------------------- ### TypeScript Regex Hygiene with String.raw Source: https://github.com/peppyhop/shop-client/blob/main/CONTRIBUTING.md Provides guidance on writing cleaner regular expressions in TypeScript, especially when dealing with complex patterns or excessive escaping. It shows examples using `String.raw` for better readability and maintainability. ```typescript // ✅ Focused extraction without excessive escaping for (const m of html.matchAll(/href=["']tel:(["']+)["']/g)) { contactLinks.tel = m[1].trim(); } for (const m of html.matchAll(/href=["']mailto:(["']+)["']/g)) { contactLinks.email = m[1].trim(); } for (const m of html.matchAll(/href=["'](["']*(?:\/contact|\/pages\/contact)["']*)["']/g)) { contactLinks.contactPage = m[1]; } // ✅ Or use String.raw for longer patterns const pattern = new RegExp(String.raw`]*name=["']description["'][^>]*content=["'](.*?)["']`, 'i'); const description = html.match(pattern)?.[1] ?? null; ``` -------------------------------- ### Debug Commands for Shop Client Source: https://github.com/peppyhop/shop-client/blob/main/RELEASE_GUIDE.md Provides common commands for local testing and debugging of the shop-client project, including building, running tests with coverage, and performing a dry run of semantic-release. ```bash # Test the build locally npm run build # Run tests with coverage npm run test:ci # Dry run semantic-release (doesn't publish) npx semantic-release --dry-run ``` -------------------------------- ### Error Handler Interface and Implementation (TypeScript) Source: https://github.com/peppyhop/shop-client/blob/main/ARCHITECTURE.md Defines a generic 'ErrorHandler' interface with 'canHandle' and 'handle' methods for managing different error types. 'NetworkErrorHandler' is provided as an example, specifically handling errors with the name 'NetworkError'. ```typescript interface ErrorHandler { canHandle(error: Error): boolean; handle(error: Error): Promise; } class NetworkErrorHandler implements ErrorHandler { canHandle(error: Error): boolean { return error.name === 'NetworkError'; } async handle(error: Error): Promise { // Custom recovery logic } } ``` -------------------------------- ### Run Shop Client Tests Source: https://github.com/peppyhop/shop-client/blob/main/CONTRIBUTING.md Command to execute the test suite for the shop-client project. This ensures that the codebase is functioning as expected. ```bash npm test ``` -------------------------------- ### TypeScript Graceful Error Handling for Data Fetching Source: https://github.com/peppyhop/shop-client/blob/main/CONTRIBUTING.md Provides an example of a TypeScript function that fetches data from a URL with graceful error handling. It checks for response success and catches network errors, returning null on failure. ```typescript // ✅ Good - Graceful error handling async function fetchData(url: string): Promise { try { const response = await fetch(url); if (!response.ok) { console.warn(`Failed to fetch ${url}: ${response.status}`); return null; } return await response.json(); } catch (error) { console.error(`Network error fetching ${url}:`, error); return null; } } ``` -------------------------------- ### Fetch Showcased Collections - collections.showcased() Source: https://context7.com/peppyhop/shop-client/llms.txt Fetches collections featured on the store's homepage. It requires an initialized ShopClient instance and returns an array of featured collection objects. ```typescript import { ShopClient } from 'shop-client'; const shop = new ShopClient('https://example-store.com'); const featured = await shop.collections.showcased(); console.log(`${featured.length} featured collections`); featured.forEach(collection => { console.log(`Featured: ${collection.title} (${collection.productsCount} products)`); }); ``` -------------------------------- ### Get Product Recommendations Source: https://github.com/peppyhop/shop-client/blob/main/README.md Fetches Shopify Ajax product recommendations for a specified product ID. Supports options for limit, intent (related/complementary), locale, and currency. Returns normalized ProductResult array. ```typescript const recos = await shop.products.recommendations(1234567890, { limit: 6, // clamps 1–10 (default 10) intent: "related", // or "complementary" (default: related) locale: "en", // defaults to "en" currency: "USD", // optional override }); ``` -------------------------------- ### Fetch All Products - products.all() Source: https://context7.com/peppyhop/shop-client/llms.txt Retrieves all products from the store with automatic pagination handling. Returns minimal product data by default, with an option to request full product details. ```APIDOC ## Fetch All Products - products.all() ### Description Retrieves all products from the store with automatic pagination handling. Returns minimal product data by default, with option to request full product details. ### Method `shop.products.all(options?: { columns?: { mode?: 'minimal' | 'full', images?: 'minimal' | 'full', options?: 'minimal' | 'full' }, currency?: string })` ### Parameters #### Path Parameters None #### Query Parameters - **columns** (object) - Optional - Specifies the level of detail for product data. - **mode** (string) - Optional - 'minimal' (default) or 'full'. - **images** (string) - Optional - 'minimal' or 'full'. - **options** (string) - Optional - 'minimal' or 'full'. - **currency** (string) - Optional - Overrides the store's default currency for pricing. #### Request Body None ### Request Example ```typescript import { ShopClient } from 'shop-client'; const shop = new ShopClient('https://example-store.com'); // Fetch all products with minimal payload (default) const minimalProducts = await shop.products.all(); console.log(`Found ${minimalProducts?.length} products`); // Minimal product fields: title, price, compareAtPrice, discount, images, featuredImage, available, productType, localizedPricing, options, url, slug, platformId // Fetch all products with full payload const fullProducts = await shop.products.all({ columns: { mode: 'full', images: 'full', options: 'full' }, }); // Full product includes: handle, vendor, tags, bodyHtml, variants, priceMin, priceMax, currency, createdAt, updatedAt, publishedAt, etc. if (fullProducts && fullProducts.length > 0) { const product = fullProducts[0]; console.log(product.title); // "Summer Dress" console.log(product.handle); // "summer-dress" console.log(product.price); // 2500 (in cents) console.log(product.available); // true console.log(product.vendor); // "Acme Brand" console.log(product.variants?.length); // 5 } // With currency override const productsInEUR = await shop.products.all({ currency: 'EUR' }); ``` ### Response #### Success Response (200) Returns an array of product objects. The structure of the objects depends on the `columns` option. - **Minimal Product Fields**: `title`, `price`, `compareAtPrice`, `discount`, `images`, `featuredImage`, `available`, `productType`, `localizedPricing`, `options`, `url`, `slug`, `platformId`. - **Full Product Fields**: Includes all minimal fields plus `handle`, `vendor`, `tags`, `bodyHtml`, `variants`, `priceMin`, `priceMax`, `currency`, `createdAt`, `updatedAt`, `publishedAt`, etc. #### Response Example ```json [ { "title": "Summer Dress", "price": 2500, "compareAtPrice": 3000, "discount": 500, "images": [ "https://cdn.shopify.com/s/files/1/0000/0000/products/dress1.jpg?v=123" ], "featuredImage": "https://cdn.shopify.com/s/files/1/0000/0000/products/dress1.jpg?v=123", "available": true, "productType": "Dresses", "localizedPricing": [ { "currency": "USD", "price": 2500, "compareAtPrice": 3000 } ], "options": [ "Size", "Color" ], "url": "/products/summer-dress", "slug": "summer-dress", "platformId": "gid://shopify/Product/1234567890" } // ... more products ] ``` ``` -------------------------------- ### NPM Test Commands for Running Tests Source: https://github.com/peppyhop/shop-client/blob/main/CONTRIBUTING.md Provides common NPM script commands for executing tests within the project. Includes commands for running all tests, watch mode, coverage, and specific files. ```bash # Run all tests npm test # Run tests in watch mode npm run test:watch # Run tests with coverage npm run test:coverage # Run specific test file npm test -- products.test.ts ``` -------------------------------- ### Fetch Showcased Products - products.showcased() Source: https://context7.com/peppyhop/shop-client/llms.txt Retrieves products that are specifically featured on the store's homepage. Allows fetching minimal data or full product details, including pricing and images. ```typescript import { ShopClient } from 'shop-client'; const shop = new ShopClient('https://example-store.com'); // Get featured products (minimal payload) const featured = await shop.products.showcased(); console.log(`${featured.length} featured products`); // With full product details const featuredFull = await shop.products.showcased({ columns: { mode: 'full', images: 'full', options: 'full' }, }); featuredFull.forEach(product => { console.log(`Featured: ${product.title} - ${product.price}`); }); ``` -------------------------------- ### Build Shop Client Project Source: https://github.com/peppyhop/shop-client/blob/main/CONTRIBUTING.md Command to build the shop-client project. This compiles the TypeScript code into JavaScript, preparing it for execution or testing. ```bash npm run build ``` -------------------------------- ### Product Operations Class Definition Source: https://github.com/peppyhop/shop-client/blob/main/ARCHITECTURE.md Defines the ProductOperations class for handling all product-related functionalities. It provides methods for retrieving all products, paginated results, finding a product by handle, getting showcased products, and discovering filter options. Supports complete product catalog access and pagination. ```typescript class ProductOperations { async all(): Promise async paginated(options: PaginationOptions): Promise async find(handle: string): Promise async showcased(): Promise async filter(): Promise } ``` -------------------------------- ### Fetch All Collections - collections.all() Source: https://context7.com/peppyhop/shop-client/llms.txt Retrieves all collections from the store with automatic pagination. It requires an initialized ShopClient instance and returns an array of collection objects. ```typescript import { ShopClient } from 'shop-client'; const shop = new ShopClient('https://example-store.com'); const collections = await shop.collections.all(); console.log(`Found ${collections.length} collections`); collections.forEach(collection => { console.log(`${collection.title} (${collection.handle})`); console.log(` Products: ${collection.productsCount}`); console.log(` Published: ${collection.publishedAt}`); if (collection.image) { console.log(` Image: ${collection.image.src}`); } }); ``` -------------------------------- ### Create GitHub Release Source: https://github.com/peppyhop/shop-client/blob/main/RELEASE_GUIDE.md Creates a GitHub Release using a specified tag, title, and notes, referencing the CHANGELOG for details. Requires the 'gh' CLI tool. ```bash gh release create vX.Y.Z \ --title "vX.Y.Z" \ --notes "See CHANGELOG for details." ``` -------------------------------- ### Collection Operations Class Definition Source: https://github.com/peppyhop/shop-client/blob/main/ARCHITECTURE.md Defines the CollectionOperations class for managing collections and their associated products. It allows retrieval of all collections, finding a collection by handle, getting showcased collections, and nested operations for fetching products within a specific collection, including paginated results. Supports collection metadata retrieval and collection-specific product fetching. ```typescript class CollectionOperations { async all(): Promise async find(handle: string): Promise async showcased(): Promise products: { async all(collectionHandle: string): Promise async paginated(collectionHandle: string, options: PaginationOptions): Promise } } ``` -------------------------------- ### Create and Push Git Tag Source: https://github.com/peppyhop/shop-client/blob/main/RELEASE_GUIDE.md Locally creates an annotated Git tag with a 'v' prefix and pushes it to the origin. This is a prerequisite for creating a GitHub Release. ```bash git tag -a vX.Y.Z -m "release: vX.Y.Z" git push origin vX.Y.Z ``` -------------------------------- ### Fetch Product Info HTML Source: https://github.com/peppyhop/shop-client/blob/main/README.md Extracts the main product description and content directly from the product page's HTML. Can fetch from the live page or use provided HTML content. Returns the extracted HTML string or null. ```typescript // Fetch from store const html = await shop.products.infoHtml("product-handle"); // Use provided HTML const htmlFromContent = await shop.products.infoHtml("product-handle", "..."); ``` -------------------------------- ### Browser Usage with CDN Source: https://github.com/peppyhop/shop-client/blob/main/README.md Demonstrates how to import and use shop-client directly in the browser using a CDN and an import map. Ensures correct MIME types for module loading. ```html ``` -------------------------------- ### Store Information - getInfo() Source: https://context7.com/peppyhop/shop-client/llms.txt Fetches comprehensive store metadata including branding, social links, contact information, featured products/collections, and detected country/currency. ```APIDOC ## Store Information - getInfo() ### Description Fetches comprehensive store metadata including branding, social links, contact information, featured products/collections, and detected country/currency. ### Method `shop.getInfo(options?: { force?: boolean })` ### Parameters #### Path Parameters None #### Query Parameters - **force** (boolean) - Optional - If true, bypasses the cache and fetches fresh data. #### Request Body None ### Request Example ```typescript import { ShopClient } from 'shop-client'; const shop = new ShopClient('https://anuki.in'); const storeInfo = await shop.getInfo(); console.log(storeInfo.name); // "Anuki" console.log(storeInfo.domain); // "https://anuki.in/" console.log(storeInfo.slug); // "anuki" console.log(storeInfo.title); // Store title from meta tags console.log(storeInfo.description); // Store description console.log(storeInfo.logoUrl); // Store logo URL console.log(storeInfo.country); // "IN" (ISO 3166-1 alpha-2) console.log(storeInfo.currency); // "INR" (ISO 4217) // Social links console.log(storeInfo.socialLinks.instagram); // "https://instagram.com/anuki" console.log(storeInfo.socialLinks.facebook); // Facebook URL if available // Contact information console.log(storeInfo.contactLinks.email); // "contact@anuki.in" console.log(storeInfo.contactLinks.tel); // Phone number console.log(storeInfo.contactLinks.contactPage); // "/pages/contact" // Featured content from homepage console.log(storeInfo.showcase.products); // ["product-handle-1", "product-handle-2"] console.log(storeInfo.showcase.collections); // ["collection-handle-1"] // Force refresh (bypass cache) const freshInfo = await shop.getInfo({ force: true }); ``` ### Response #### Success Response (200) - **name** (string) - The name of the store. - **domain** (string) - The domain URL of the store. - **slug** (string) - A unique slug for the store. - **title** (string) - The title of the store from meta tags. - **description** (string) - The description of the store. - **logoUrl** (string) - The URL of the store's logo. - **country** (string) - The ISO 3166-1 alpha-2 country code. - **currency** (string) - The ISO 4217 currency code. - **socialLinks** (object) - An object containing social media links. - **instagram** (string) - Instagram URL. - **facebook** (string) - Facebook URL. - ... other social links - **contactLinks** (object) - An object containing contact information. - **email** (string) - Contact email address. - **tel** (string) - Contact phone number. - **contactPage** (string) - URL path to the contact page. - **showcase** (object) - Featured content from the homepage. - **products** (array) - Array of product handles. - **collections** (array) - Array of collection handles. #### Response Example ```json { "name": "Anuki", "domain": "https://anuki.in/", "slug": "anuki", "title": "Anuki Official Store", "description": "Shop the latest fashion trends from Anuki.", "logoUrl": "https://cdn.shopify.com/s/files/1/0000/0000/t/1/assets/logo.png?v=1234567890", "country": "IN", "currency": "INR", "socialLinks": { "instagram": "https://instagram.com/anuki", "facebook": null }, "contactLinks": { "email": "contact@anuki.in", "tel": "+91 1234567890", "contactPage": "/pages/contact" }, "showcase": { "products": ["summer-dress", "winter-coat"], "collections": ["new-arrivals"] } } ``` ``` -------------------------------- ### Fetch Paginated Products - products.paginated() Source: https://context7.com/peppyhop/shop-client/llms.txt Retrieves products in batches, suitable for large catalogs or infinite scrolling. Supports manual control over page number and limit. Allows specifying currency and detailed product columns. ```typescript import { ShopClient } from 'shop-client'; const shop = new ShopClient('https://example-store.com'); // First page with default limit (250) const firstPage = await shop.products.paginated(); console.log(`Page 1: ${firstPage?.length} products`); // Second page with custom limit const secondPage = await shop.products.paginated({ page: 2, limit: 50, }); // With full product data and currency override const productsPage = await shop.products.paginated({ page: 1, limit: 24, currency: 'GBP', columns: { mode: 'full', images: 'full', options: 'full' }, }); // Implement pagination loop let page = 1; let allProducts = []; while (true) { const batch = await shop.products.paginated({ page, limit: 250 }); if (!batch || batch.length === 0) break; allProducts.push(...batch); if (batch.length < 250) break; page++; } ``` -------------------------------- ### Fetch Product Recommendations - products.recommendations() Source: https://context7.com/peppyhop/shop-client/llms.txt Retrieves product recommendations (related or complementary) based on a given product ID. Supports specifying the number of recommendations, intent (related/complementary), locale, and currency. ```typescript import { ShopClient } from 'shop-client'; const shop = new ShopClient('https://example-store.com'); // Get related products const related = await shop.products.recommendations(1234567890, { limit: 6, // Max 10 (clamped 1-10) intent: 'related', // 'related' | 'complementary' locale: 'en', currency: 'USD', }); if (related) { console.log(`Found ${related.length} related products`); related.forEach(product => { console.log(`- ${product.title}`); }); } // Get complementary products (for cross-selling) const complementary = await shop.products.recommendations(1234567890, { intent: 'complementary', limit: 4, }); ``` -------------------------------- ### Utility Functions for Normalization and Parsing in Shop-Client Source: https://context7.com/peppyhop/shop-client/llms.txt Provides various utility functions for common tasks such as sanitizing domains, safely parsing dates, calculating discounts, extracting domain names, generating slugs, building variant keys, and detecting store countries. These functions help in data normalization and processing. Dependencies include the 'shop-client' library. ```typescript import { sanitizeDomain, safeParseDate, calculateDiscount, extractDomainWithoutSuffix, generateStoreSlug, genProductSlug, buildVariantKey, detectShopCountry, } from 'shop-client'; // Domain normalization sanitizeDomain('https://www.example.com'); // "example.com" sanitizeDomain('www.example.com', { stripWWW: false }); // "www.example.com" sanitizeDomain('http://example.com/path'); // "example.com" // Safe date parsing (returns undefined for invalid dates) safeParseDate('2024-10-31T12:34:56Z'); // Date object safeParseDate(''); // undefined safeParseDate('not-a-date'); // undefined // Discount calculation (percentage, rounded to integer) calculateDiscount(8000, 10000); // 20 (20% off) // Extract domain without TLD suffix extractDomainWithoutSuffix('www.example.co.uk'); // "example" // Generate store slug from URL generateStoreSlug('https://shop.example.com'); // "shop-example-com" // Generate product slug with vendor prefix genProductSlug({ handle: 'summer-dress', storeDomain: 'https://acme.com' }); // "summer-dress-by-acme" // Build variant key for lookups const key = buildVariantKey({ Size: 'XL', Color: 'Blue' }); // "color__blue____size__xl" // Detect store country with confidence const result = await detectShopCountry('anuki.in'); // { country: 'IN', confidence: 0.9, signals: [...] } ``` -------------------------------- ### Handle Product Fetch Errors in TypeScript Source: https://github.com/peppyhop/shop-client/blob/main/README.md Demonstrates how to use a try-catch block to handle potential errors when fetching a product using the shop client. It specifically shows how to catch network errors, invalid domain issues, and gracefully log the error message. The `find` method returns null if a product is not found. ```typescript try { const product = await shop.products.find("non-existent-handle"); // Returns null for not found } catch (error) { // Handles network errors, invalid domains, etc. console.error('Error fetching product:', error.message); } ``` -------------------------------- ### Package.json Exports Configuration (JSON) Source: https://github.com/peppyhop/shop-client/blob/main/ARCHITECTURE.md Defines the distribution strategy for the project's output, specifying entry points for different module formats (CommonJS, ESM, UMD) and type declarations. This configuration is crucial for consumers of the package. ```json { "main": "dist/index.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts", "exports": { ".": { "import": "./dist/index.esm.js", "require": "./dist/index.js", "types": "./dist/index.d.ts" } } } ``` -------------------------------- ### TypeScript Product Type Definition Source: https://github.com/peppyhop/shop-client/blob/main/llm.txt Defines the structure of a Product object, including its ID, title, handle, description, price, availability, images, variants, and other relevant details. This type ensures data consistency and enables type-safe operations. ```typescript interface Product { id: string; title: string; handle: string; description: string; price: number; compareAtPrice?: number; available: boolean; images: ProductImage[]; variants: ProductVariant[]; vendor: string; productType: string; tags: string[]; createdAt: string; updatedAt: string; currency: string; } ```