shop-client 3.17.0 → 3.18.1

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-BmJArla2.js';
2
2
 
3
3
  declare function buildEnrichPrompt(args: {
4
4
  bodyInput: string;
@@ -13,8 +13,8 @@ import {
13
13
  htmlToMarkdown,
14
14
  mergeWithLLM,
15
15
  pruneBreakdownForSignals
16
- } from "../chunk-5TGMDRUF.mjs";
17
- import "../chunk-O77Z6OBJ.mjs";
16
+ } from "../chunk-OSMMFHDC.mjs";
17
+ import "../chunk-4GPP2KXF.mjs";
18
18
  export {
19
19
  buildClassifyPrompt,
20
20
  buildClassifyPromptForProduct,
@@ -177,6 +177,9 @@ async function rateLimitedFetch(input, init) {
177
177
  timeoutMs: _timeoutMs,
178
178
  ...fetchInit
179
179
  } = effInit;
180
+ if (fetchInit.redirect === void 0) {
181
+ fetchInit.redirect = "follow";
182
+ }
180
183
  const klass = init == null ? void 0 : init.rateLimitClass;
181
184
  const byClass = klass ? classLimiters.get(klass) : void 0;
182
185
  const byHost = getHostLimiter(getHost(input));
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  rateLimitedFetch
3
- } from "./chunk-O77Z6OBJ.mjs";
3
+ } from "./chunk-4GPP2KXF.mjs";
4
4
  import {
5
5
  formatPrice
6
6
  } from "./chunk-U3RQRBXZ.mjs";
@@ -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.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,6 +1,6 @@
1
1
  import {
2
2
  rateLimitedFetch
3
- } from "./chunk-O77Z6OBJ.mjs";
3
+ } from "./chunk-4GPP2KXF.mjs";
4
4
  import {
5
5
  detectShopCountry
6
6
  } from "./chunk-SBHTEKLB.mjs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  rateLimitedFetch
3
- } from "./chunk-O77Z6OBJ.mjs";
3
+ } from "./chunk-4GPP2KXF.mjs";
4
4
  import {
5
5
  formatPrice
6
6
  } from "./chunk-U3RQRBXZ.mjs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  rateLimitedFetch
3
- } from "./chunk-O77Z6OBJ.mjs";
3
+ } from "./chunk-4GPP2KXF.mjs";
4
4
 
5
5
  // src/ai/enrich.ts
6
6
  import TurndownService from "turndown";
@@ -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-BmJArla2.js';
3
3
 
4
4
  /**
5
5
  * Interface for collection operations
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createCollectionOperations
3
- } from "./chunk-242GBM2V.mjs";
4
- import "./chunk-O77Z6OBJ.mjs";
3
+ } from "./chunk-GYQQU54C.mjs";
4
+ import "./chunk-4GPP2KXF.mjs";
5
5
  import "./chunk-U3RQRBXZ.mjs";
6
6
  export {
7
7
  createCollectionOperations
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-BmJArla2.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-BmJArla2.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
@@ -3,23 +3,23 @@ import {
3
3
  } from "./chunk-W4SF6W2P.mjs";
4
4
  import {
5
5
  createCollectionOperations
6
- } from "./chunk-242GBM2V.mjs";
6
+ } from "./chunk-GYQQU54C.mjs";
7
7
  import {
8
8
  createProductOperations
9
- } from "./chunk-3KRUT5BD.mjs";
9
+ } from "./chunk-64S4UWAH.mjs";
10
10
  import {
11
11
  createShopOperations,
12
12
  getInfoForShop
13
- } from "./chunk-YWAW6C74.mjs";
13
+ } from "./chunk-BNTNHHDI.mjs";
14
14
  import {
15
15
  classifyProduct,
16
16
  determineStoreType,
17
17
  generateSEOContent
18
- } from "./chunk-5TGMDRUF.mjs";
18
+ } from "./chunk-OSMMFHDC.mjs";
19
19
  import {
20
20
  configureRateLimit,
21
21
  rateLimitedFetch
22
- } from "./chunk-O77Z6OBJ.mjs";
22
+ } from "./chunk-4GPP2KXF.mjs";
23
23
  import {
24
24
  detectShopCountry
25
25
  } from "./chunk-SBHTEKLB.mjs";
@@ -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-BmJArla2.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. Required for authentication via x-api-key header.
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,7 +1,7 @@
1
1
  import {
2
2
  createProductOperations
3
- } from "./chunk-3KRUT5BD.mjs";
4
- import "./chunk-O77Z6OBJ.mjs";
3
+ } from "./chunk-64S4UWAH.mjs";
4
+ import "./chunk-4GPP2KXF.mjs";
5
5
  import "./chunk-U3RQRBXZ.mjs";
6
6
  export {
7
7
  createProductOperations
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-BmJArla2.js';
2
2
 
3
3
  /**
4
4
  * Store operations interface for managing store-related functionality.
package/dist/store.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createShopOperations
3
- } from "./chunk-YWAW6C74.mjs";
4
- import "./chunk-O77Z6OBJ.mjs";
3
+ } from "./chunk-BNTNHHDI.mjs";
4
+ import "./chunk-4GPP2KXF.mjs";
5
5
  import "./chunk-SBHTEKLB.mjs";
6
6
  import "./chunk-U3RQRBXZ.mjs";
7
7
  export {
@@ -435,6 +435,60 @@ type SEOContent = {
435
435
  tags: string[];
436
436
  marketingCopy: string;
437
437
  };
438
+ /**
439
+ * Contextual image information extracted from product content.
440
+ */
441
+ type EnhancedProductImage = {
442
+ /** The text surrounding the image reference. */
443
+ textContext: string;
444
+ /** The image URL. */
445
+ url: string;
446
+ /** The image alt text. */
447
+ alt: string;
448
+ };
449
+ /**
450
+ * Structured canonical product data extracted by AI.
451
+ */
452
+ type EnhancedProductCanonical = {
453
+ /** The product title. */
454
+ title: string;
455
+ /** A brief summary of the product. */
456
+ summary: string;
457
+ /** Key highlights or features of the product. */
458
+ highlights: string[];
459
+ /** Material information (array of strings or object). */
460
+ materials: unknown;
461
+ /** Fit and sizing information. */
462
+ fit_and_size: unknown;
463
+ /** Care instructions. */
464
+ care: unknown;
465
+ /** Unique selling points. */
466
+ what_makes_it_special: unknown;
467
+ /** Information that was looked for but not found. */
468
+ missing_info: unknown[];
469
+ /** List of contextual images found in the description. */
470
+ images: EnhancedProductImage[];
471
+ };
472
+ /**
473
+ * The full enrichment result containing both structured and markdown formats.
474
+ */
475
+ type EnhancedProductEnrichment = {
476
+ /** The structured canonical data. */
477
+ canonical: EnhancedProductCanonical;
478
+ /** The generated markdown content. */
479
+ markdown: string;
480
+ };
481
+ /**
482
+ * The response object from the enhanced product search.
483
+ */
484
+ type EnhancedProductResponse = {
485
+ /** The original Shopify product data. */
486
+ shopify: ShopifyProduct;
487
+ /** The AI-enriched content. */
488
+ enrichment: EnhancedProductEnrichment;
489
+ /** Cache status of the response (e.g., 'hit', 'miss'). */
490
+ cache: string;
491
+ };
438
492
  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
493
 
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 };
494
+ 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-BmJArla2.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-BmJArla2.js';
2
2
 
3
3
  declare function extractDomainWithoutSuffix(domain: string): string | null;
4
4
  declare function generateStoreSlug(domain: string): string;
@@ -2,7 +2,7 @@ import {
2
2
  configureRateLimit,
3
3
  getRateLimitStatus,
4
4
  rateLimitedFetch
5
- } from "../chunk-O77Z6OBJ.mjs";
5
+ } from "../chunk-4GPP2KXF.mjs";
6
6
  export {
7
7
  configureRateLimit,
8
8
  getRateLimitStatus,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shop-client",
3
- "version": "3.17.0",
3
+ "version": "3.18.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.mjs",
6
6
  "module": "./dist/index.mjs",