import fs from 'node:fs' import path from 'node:path' import { PROJECT_ROOT } from '../../config/runtime.js' const ORDER_FULFILLMENT_BINDINGS_FILE_PATH = path.join(PROJECT_ROOT, 'data', 'order-fulfillment-bindings.json') export function getOrderFulfillmentBindingsFilePath() { return ORDER_FULFILLMENT_BINDINGS_FILE_PATH } export function getOrderFulfillmentBindingConfigs() { return loadOrderFulfillmentBindingConfigsFromFile() } export function getLegacyOrderFulfillmentBindingConfigs() { return filterLegacyOrderFulfillmentBindings(getOrderFulfillmentBindingConfigs()) } export function saveOrderFulfillmentBindingConfigs(rawValue) { const normalized = normalizeOrderFulfillmentBindingConfigs(rawValue) fs.mkdirSync(path.dirname(ORDER_FULFILLMENT_BINDINGS_FILE_PATH), { recursive: true }) fs.writeFileSync( ORDER_FULFILLMENT_BINDINGS_FILE_PATH, `${JSON.stringify(normalized, null, 2)}\n`, 'utf8', ) return normalized } function loadOrderFulfillmentBindingConfigsFromFile() { if (!fs.existsSync(ORDER_FULFILLMENT_BINDINGS_FILE_PATH)) { return [] } try { const rawText = fs.readFileSync(ORDER_FULFILLMENT_BINDINGS_FILE_PATH, 'utf8') const parsed = JSON.parse(rawText) return normalizeOrderFulfillmentBindingConfigs(parsed) } catch { return [] } } function normalizeOrderFulfillmentBindingConfigs(rawValue) { if (!Array.isArray(rawValue)) { return [] } return rawValue .map((item) => normalizeOrderFulfillmentBinding(item)) .filter(Boolean) } export function filterLegacyOrderFulfillmentBindings(bindings = []) { return (Array.isArray(bindings) ? bindings : []).filter((item) => !isKuaishouCloudFulfillmentBinding(item)) } export function isKuaishouCloudFulfillmentBinding(binding = {}) { return String(binding?.provider || '').trim() === 'khhao' && String(binding?.platform || '').trim() === 'kuaishou' } function normalizeOrderFulfillmentBinding(rawValue) { if (!isPlainObject(rawValue)) { return null } const provider = String(rawValue.provider || 'agiso').trim() || 'agiso' const platform = String(rawValue.platform || '').trim() const shopId = String(rawValue.shopId || '').trim() const shopName = String(rawValue.shopName || '').trim() const khhaoShopId = String(rawValue.khhaoShopId || '').trim() const skuCode = String(rawValue.skuCode || '').trim() const skuName = String(rawValue.skuName || '').trim() const profileKey = String(rawValue.profileKey || '').trim() || 'manual_review' const priority = normalizePriority(rawValue.priority) const enabled = rawValue.enabled !== false const config = normalizeJsonObject(rawValue.config) const match = normalizeOrderFulfillmentMatch(rawValue.match) if (!skuCode || !match) { return null } return { provider, platform, shopId, shopName, khhaoShopId, skuCode, skuName, profileKey, enabled, priority, config, match, } } function normalizeOrderFulfillmentMatch(rawValue) { if (!isPlainObject(rawValue)) { return null } const externalSkuCode = String(rawValue.externalSkuCode || '').trim() const externalItemId = String(rawValue.externalItemId || '').trim() const externalSkuName = String(rawValue.externalSkuName || '').trim() if (!externalSkuCode && !externalItemId && !externalSkuName) { return null } return { externalSkuCode, externalItemId, externalSkuName, config: normalizeJsonObject(rawValue.config), } } function normalizePriority(value) { const parsed = Number(value) if (!Number.isFinite(parsed)) { return 100 } return Math.max(1, Math.round(parsed)) } function normalizeJsonObject(value) { return isPlainObject(value) ? value : {} } function isPlainObject(value) { return Object.prototype.toString.call(value) === '[object Object]' }