import type { ScrapePayload } from './types.js'; import { requestApiWithAutoRefresh } from '@clawd/auth-runtime'; import type { ApiResponse, EnvConfig } from '@clawd/auth-runtime'; type Defaults = { optimizeImages: boolean; optimizeTitles: boolean; optimizeVariants: boolean; needTranslate: boolean; }; export function buildPayloadFromUrl( url: string, needTranslateOverride: string, defaults: Defaults, ): ScrapePayload { if (!url || url.trim() === '') { throw new Error('url is required'); } const payload: ScrapePayload = { url: url.trim(), optimizeImages: defaults.optimizeImages, optimizeTitles: defaults.optimizeTitles, optimizeVariants: defaults.optimizeVariants, needTranslate: defaults.needTranslate, }; if (needTranslateOverride && needTranslateOverride.trim() !== '') { payload.needTranslate = parseBoolean(needTranslateOverride); } return payload; } export function validatePayloadJson(raw: string): ScrapePayload { let data: unknown; try { data = JSON.parse(raw); } catch (error) { throw new Error(`invalid payload json: ${(error as SyntaxError).message}`); } if (typeof data !== 'object' || data === null || Array.isArray(data)) { throw new Error('payload must be a JSON object'); } const obj = data as Record; if (!obj.url) { throw new Error('payload.url is required'); } return { url: obj.url as string, optimizeImages: parseBoolean(obj.optimizeImages ?? true), optimizeTitles: parseBoolean(obj.optimizeTitles ?? true), optimizeVariants: parseBoolean(obj.optimizeVariants ?? true), needTranslate: parseBoolean(obj.needTranslate ?? false), }; } export async function scrapeProduct( config: EnvConfig, ecomBase: string, payload: ScrapePayload, dryRun: boolean, accessToken?: string, ): Promise { return requestApiWithAutoRefresh( 'POST', `${ecomBase}/ecom/tasks/scrape`, dryRun, config, JSON.stringify(payload), accessToken, ); } function parseBoolean(value: unknown): boolean { const str = String(value).trim().toLowerCase(); return ['1', 'true', 'yes', 'y'].includes(str); }