shop-client 3.17.0 → 3.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { O as OpenRouterConfig, l as ProductClassification, m as SEOContent, n as SystemUserPrompt, a as ShopifySingleProduct } from '../types-w9n4csBQ.js';
1
+ import { O as OpenRouterConfig, l as ProductClassification, m as SEOContent, n as SystemUserPrompt, a as ShopifySingleProduct } from '../types-B4WDm14E.js';
2
2
 
3
3
  declare function buildEnrichPrompt(args: {
4
4
  bodyInput: string;
@@ -298,6 +298,75 @@ function createProductOperations(baseUrl, storeDomain, fetchProducts, productsDt
298
298
  );
299
299
  return finalProducts != null ? finalProducts : [];
300
300
  }
301
+ async function findEnhancedInternal(productHandle, options) {
302
+ var _a;
303
+ const apiKey = options == null ? void 0 : options.apiKey;
304
+ if (!apiKey || typeof apiKey !== "string" || !apiKey.trim()) {
305
+ throw new Error("apiKey is required");
306
+ }
307
+ const baseProduct = await findInternal(productHandle, { minimal: false });
308
+ if (!baseProduct) return null;
309
+ let updatedAt = (_a = baseProduct.updatedAt) == null ? void 0 : _a.toISOString();
310
+ if (updatedAt == null ? void 0 : updatedAt.endsWith(".000Z")) {
311
+ updatedAt = updatedAt.replace(".000Z", "Z");
312
+ }
313
+ if (!updatedAt) {
314
+ const url = `${baseUrl}products/${encodeURIComponent(baseProduct.handle)}.js`;
315
+ const resp2 = await rateLimitedFetch(url, {
316
+ rateLimitClass: "products:single",
317
+ timeoutMs: 7e3,
318
+ retry: { maxRetries: 1, baseDelayMs: 200 }
319
+ });
320
+ if (!resp2.ok) {
321
+ if (resp2.status === 404) return null;
322
+ throw new Error(`HTTP ${resp2.status}: ${resp2.statusText}`);
323
+ }
324
+ const raw = await resp2.json();
325
+ if (typeof raw.updated_at === "string" && raw.updated_at.trim()) {
326
+ updatedAt = raw.updated_at;
327
+ } else {
328
+ throw new Error("updatedAt missing for product");
329
+ }
330
+ }
331
+ const endpoint = typeof (options == null ? void 0 : options.endpoint) === "string" && options.endpoint.trim() || "https://shopify-product-enrichment-worker.ninjacode.workers.dev";
332
+ let hostname = storeDomain;
333
+ try {
334
+ hostname = new URL(storeDomain).hostname;
335
+ } catch {
336
+ hostname = storeDomain.replace(/^https?:\/\//, "").replace(/\/.*$/, "");
337
+ }
338
+ const resp = await rateLimitedFetch(endpoint, {
339
+ method: "POST",
340
+ headers: {
341
+ "content-type": "application/json",
342
+ "x-api-key": apiKey
343
+ },
344
+ body: JSON.stringify({
345
+ storeDomain: hostname,
346
+ handle: baseProduct.handle,
347
+ updatedAt
348
+ }),
349
+ rateLimitClass: "products:enhanced",
350
+ timeoutMs: 15e3,
351
+ retry: {
352
+ maxRetries: 2,
353
+ baseDelayMs: 300,
354
+ retryOnStatuses: [429, 500, 502, 503, 504]
355
+ }
356
+ });
357
+ if (!resp.ok) {
358
+ throw new Error(`HTTP ${resp.status}: ${resp.statusText}`);
359
+ }
360
+ const data = await resp.json();
361
+ if (!data || typeof data !== "object" || Array.isArray(data)) {
362
+ throw new Error("Invalid enhanced product response");
363
+ }
364
+ const o = data;
365
+ if (!("shopify" in o) || !("enrichment" in o) || !("cache" in o)) {
366
+ throw new Error("Invalid enhanced product response");
367
+ }
368
+ return data;
369
+ }
301
370
  const operations = {
302
371
  /**
303
372
  * Fetches all products from the store across all pages.
@@ -375,6 +444,7 @@ function createProductOperations(baseUrl, storeDomain, fetchProducts, productsDt
375
444
  minimal: false,
376
445
  currency: options == null ? void 0 : options.currency
377
446
  }),
447
+ findEnhanced: async (productHandle, options) => findEnhancedInternal(productHandle, options),
378
448
  /**
379
449
  * Enrich a product by generating merged markdown from body_html and product page.
380
450
  * Adds `enriched_content` to the returned product.
@@ -1,5 +1,5 @@
1
1
  import { ShopInfo } from './store.js';
2
- import { C as Collection, f as CurrencyCode, P as Product, M as MinimalProduct, b as ShopifyCollection } from './types-w9n4csBQ.js';
2
+ import { C as Collection, f as CurrencyCode, P as Product, M as MinimalProduct, b as ShopifyCollection } from './types-B4WDm14E.js';
3
3
 
4
4
  /**
5
5
  * Interface for collection operations
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { O as OpenRouterConfig, S as ShopifyProduct, P as Product, M as MinimalProduct, a as ShopifySingleProduct, b as ShopifyCollection, C as Collection, J as JsonLdEntry, c as StoreTypeBreakdown } from './types-w9n4csBQ.js';
2
- export { d as CountryDetectionResult, e as CountryScores, f as CurrencyCode, L as LocalizedPricing, g as MetaTag, h as ProductImage, i as ProductOption, j as ProductVariant, k as ProductVariantImage } from './types-w9n4csBQ.js';
1
+ import { O as OpenRouterConfig, S as ShopifyProduct, P as Product, M as MinimalProduct, a as ShopifySingleProduct, b as ShopifyCollection, C as Collection, J as JsonLdEntry, c as StoreTypeBreakdown } from './types-B4WDm14E.js';
2
+ export { d as CountryDetectionResult, e as CountryScores, f as CurrencyCode, L as LocalizedPricing, g as MetaTag, h as ProductImage, i as ProductOption, j as ProductVariant, k as ProductVariantImage } from './types-B4WDm14E.js';
3
3
  import { CheckoutOperations } from './checkout.js';
4
4
  import { CollectionOperations } from './collections.js';
5
5
  import { ProductOperations } from './products.js';
package/dist/index.mjs CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-242GBM2V.mjs";
7
7
  import {
8
8
  createProductOperations
9
- } from "./chunk-3KRUT5BD.mjs";
9
+ } from "./chunk-6XDBGOFZ.mjs";
10
10
  import {
11
11
  createShopOperations,
12
12
  getInfoForShop
@@ -1,5 +1,5 @@
1
1
  import { ShopInfo } from './store.js';
2
- import { f as CurrencyCode, P as Product, l as ProductClassification, m as SEOContent, M as MinimalProduct, S as ShopifyProduct, a as ShopifySingleProduct, O as OpenRouterConfig } from './types-w9n4csBQ.js';
2
+ import { f as CurrencyCode, P as Product, E as EnhancedProductResponse, l as ProductClassification, m as SEOContent, M as MinimalProduct, S as ShopifyProduct, a as ShopifySingleProduct, O as OpenRouterConfig } from './types-B4WDm14E.js';
3
3
 
4
4
  /**
5
5
  * Interface for product operations
@@ -28,6 +28,18 @@ interface ProductOperations {
28
28
  find(productHandle: string, options?: {
29
29
  currency?: CurrencyCode;
30
30
  }): Promise<Product | null>;
31
+ /**
32
+ * Finds a product and enhances it with AI-generated content using an external service.
33
+ *
34
+ * @param productHandle - The handle of the product to find.
35
+ * @param options - Options for the request.
36
+ * @param options.apiKey - API key for the enhancement service.
37
+ * @param options.endpoint - Optional custom endpoint URL for the enhancement service. Defaults to the standard worker URL.
38
+ */
39
+ findEnhanced(productHandle: string, options?: {
40
+ apiKey?: string;
41
+ endpoint?: string;
42
+ }): Promise<EnhancedProductResponse | null>;
31
43
  /**
32
44
  * Finds a product by handle and enriches its content using LLM.
33
45
  * Requires an OpenRouter API key via options.apiKey or ShopClient options.
package/dist/products.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createProductOperations
3
- } from "./chunk-3KRUT5BD.mjs";
3
+ } from "./chunk-6XDBGOFZ.mjs";
4
4
  import "./chunk-O77Z6OBJ.mjs";
5
5
  import "./chunk-U3RQRBXZ.mjs";
6
6
  export {
package/dist/store.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { J as JsonLdEntry, d as CountryDetectionResult, f as CurrencyCode } from './types-w9n4csBQ.js';
1
+ import { J as JsonLdEntry, d as CountryDetectionResult, f as CurrencyCode } from './types-B4WDm14E.js';
2
2
 
3
3
  /**
4
4
  * Store operations interface for managing store-related functionality.
@@ -435,6 +435,37 @@ type SEOContent = {
435
435
  tags: string[];
436
436
  marketingCopy: string;
437
437
  };
438
+ type EnhancedProductImage = {
439
+ textContext: string;
440
+ url: string;
441
+ alt: string;
442
+ };
443
+ type EnhancedProductCanonical = {
444
+ title: string;
445
+ summary: string;
446
+ highlights: string[];
447
+ materials: unknown;
448
+ fit_and_size: unknown;
449
+ care: unknown;
450
+ what_makes_it_special: unknown;
451
+ missing_info: unknown[];
452
+ images: EnhancedProductImage[];
453
+ };
454
+ type EnhancedProductEnrichment = {
455
+ canonical: EnhancedProductCanonical;
456
+ markdown: string;
457
+ };
458
+ /**
459
+ * The response object from the enhanced product search.
460
+ */
461
+ type EnhancedProductResponse = {
462
+ /** The original Shopify product data. */
463
+ shopify: ShopifyProduct;
464
+ /** The AI-enriched content. */
465
+ enrichment: EnhancedProductEnrichment;
466
+ /** Cache status of the response (e.g., 'hit', 'miss'). */
467
+ cache: string;
468
+ };
438
469
  type StoreTypeBreakdown = Partial<Record<"adult_male" | "adult_female" | "kid_male" | "kid_female" | "generic", Partial<Record<"clothing" | "beauty" | "accessories" | "home-decor" | "food-and-beverages", string[]>>>>;
439
470
 
440
- export type { Collection as C, JsonLdEntry as J, LocalizedPricing as L, MinimalProduct as M, OpenRouterConfig as O, Product as P, ShopifyProduct as S, ShopifySingleProduct as a, ShopifyCollection as b, StoreTypeBreakdown as c, CountryDetectionResult as d, CountryScores as e, CurrencyCode as f, MetaTag as g, ProductImage as h, ProductOption as i, ProductVariant as j, ProductVariantImage as k, ProductClassification as l, SEOContent as m, SystemUserPrompt as n };
471
+ export type { Collection as C, EnhancedProductResponse as E, JsonLdEntry as J, LocalizedPricing as L, MinimalProduct as M, OpenRouterConfig as O, Product as P, ShopifyProduct as S, ShopifySingleProduct as a, ShopifyCollection as b, StoreTypeBreakdown as c, CountryDetectionResult as d, CountryScores as e, CurrencyCode as f, MetaTag as g, ProductImage as h, ProductOption as i, ProductVariant as j, ProductVariantImage as k, ProductClassification as l, SEOContent as m, SystemUserPrompt as n };
@@ -1,4 +1,4 @@
1
- import { d as CountryDetectionResult } from '../types-w9n4csBQ.js';
1
+ import { d as CountryDetectionResult } from '../types-B4WDm14E.js';
2
2
 
3
3
  /**
4
4
  * Detects the country of a Shopify store by analyzing various signals in the HTML content.
@@ -1,4 +1,4 @@
1
- import { f as CurrencyCode } from '../types-w9n4csBQ.js';
1
+ import { f as CurrencyCode } from '../types-B4WDm14E.js';
2
2
 
3
3
  declare function extractDomainWithoutSuffix(domain: string): string | null;
4
4
  declare function generateStoreSlug(domain: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shop-client",
3
- "version": "3.17.0",
3
+ "version": "3.18.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.mjs",
6
6
  "module": "./dist/index.mjs",