export const PRODUCT_PLANNING_API_CONFIG_KEY = "product_planning_api_config"; export type ProductPlanningApiConfig = { oneboundBaseUrl: string; taobaoApiKey: string; taobaoApiSecret: string; detailPlusBaseUrl: string; detailPlusInternalBaseUrl: string; detailPlusApiKey: string; qaApiUrl: string; qaToken: string; saleApiUrl: string; saleToken: string; planningDbHost: string; planningDbPort: string; planningDbDatabase: string; planningDbUser: string; planningDbPassword: string; planningDbCharset: string; planningDbSsl: boolean; }; const DEFAULT_ONEBOUND_BASE_URL = "https://api-gw.onebound.cn"; const DEFAULT_DETAIL_PLUS_BASE_URL = "http://ltai5tdb2ogyj59fquyedh.yydd.ai:18082/api/public/taobao-detail-plus"; const DEFAULT_QA_API_URL = "http://119.91.237.2:5432/taobao_social_feed_aggregate"; const DEFAULT_SALE_API_URL = "http://119.91.237.2:5432/taobao_item_month_sale"; function normalizeUrl(value: unknown, fallback: string) { const normalized = String(value || "").trim().replace(/\/+$/, ""); const normalizedFallback = String(fallback || "").trim().replace(/\/+$/, ""); return normalized || normalizedFallback; } function normalizeSecret(value: unknown, fallback = "") { const normalized = String(value || "").trim(); const normalizedFallback = String(fallback || "").trim(); return normalized || normalizedFallback; } function normalizeBoolean(value: unknown, fallback = false) { if (typeof value === "boolean") return value; if (typeof value === "string") { const normalized = value.trim().toLowerCase(); if (["true", "1", "yes", "y", "on"].includes(normalized)) return true; if (["false", "0", "no", "n", "off"].includes(normalized)) return false; } return fallback; } export function defaultProductPlanningApiConfig(): ProductPlanningApiConfig { return { oneboundBaseUrl: DEFAULT_ONEBOUND_BASE_URL, taobaoApiKey: "", taobaoApiSecret: "", detailPlusBaseUrl: DEFAULT_DETAIL_PLUS_BASE_URL, detailPlusInternalBaseUrl: "", detailPlusApiKey: "", qaApiUrl: DEFAULT_QA_API_URL, qaToken: "", saleApiUrl: DEFAULT_SALE_API_URL, saleToken: "", planningDbHost: "", planningDbPort: "3306", planningDbDatabase: "", planningDbUser: "", planningDbPassword: "", planningDbCharset: "utf8mb4", planningDbSsl: false, }; } export function normalizeProductPlanningApiConfig( value: unknown, fallback?: Partial ): ProductPlanningApiConfig { const raw = value && typeof value === "object" && !Array.isArray(value) ? (value as Record) : {}; return { oneboundBaseUrl: normalizeUrl(raw.oneboundBaseUrl, fallback?.oneboundBaseUrl || DEFAULT_ONEBOUND_BASE_URL), taobaoApiKey: normalizeSecret(raw.taobaoApiKey, fallback?.taobaoApiKey || ""), taobaoApiSecret: normalizeSecret(raw.taobaoApiSecret, fallback?.taobaoApiSecret || ""), detailPlusBaseUrl: normalizeUrl( raw.detailPlusBaseUrl, fallback?.detailPlusBaseUrl || DEFAULT_DETAIL_PLUS_BASE_URL ), detailPlusInternalBaseUrl: normalizeUrl( raw.detailPlusInternalBaseUrl, fallback?.detailPlusInternalBaseUrl || "" ), detailPlusApiKey: normalizeSecret(raw.detailPlusApiKey, fallback?.detailPlusApiKey || ""), qaApiUrl: normalizeUrl(raw.qaApiUrl, fallback?.qaApiUrl || DEFAULT_QA_API_URL), qaToken: normalizeSecret(raw.qaToken, fallback?.qaToken || ""), saleApiUrl: normalizeUrl(raw.saleApiUrl, fallback?.saleApiUrl || DEFAULT_SALE_API_URL), saleToken: normalizeSecret(raw.saleToken, fallback?.saleToken || ""), planningDbHost: normalizeSecret(raw.planningDbHost, fallback?.planningDbHost || ""), planningDbPort: normalizeSecret(raw.planningDbPort, fallback?.planningDbPort || "3306"), planningDbDatabase: normalizeSecret(raw.planningDbDatabase, fallback?.planningDbDatabase || ""), planningDbUser: normalizeSecret(raw.planningDbUser, fallback?.planningDbUser || ""), planningDbPassword: normalizeSecret(raw.planningDbPassword, fallback?.planningDbPassword || ""), planningDbCharset: normalizeSecret(raw.planningDbCharset, fallback?.planningDbCharset || "utf8mb4"), planningDbSsl: normalizeBoolean(raw.planningDbSsl, fallback?.planningDbSsl || false), }; }