import catalog from './agent-rule-catalog.json' import { desktopAssert } from './contract.mjs' import { createHash } from 'node:crypto' const canonical = (value: unknown): string => JSON.stringify(value, (_, item) => item && typeof item === 'object' && !Array.isArray(item) ? Object.fromEntries(Object.keys(item).sort().map(key => [key, item[key]])) : item) const contentHash = (value: unknown) => createHash('sha256').update(canonical(value)).digest('hex') function scopedCatalog(binding: typeof catalog.bindings[number]) { const shop = catalog.shops.find(item => item.id === binding.shopId)! return { ...catalog, brands: catalog.brands.filter(item => item.id === shop.brandId), shops: [shop], categories: catalog.categories.filter(item => item.id === binding.categoryId), bindings: [binding] } } /** Versioned source package. Never executes the knowledge-base's software workflow. */ export function desktopAgentRules(bindingId: string | null) { const ready = catalog.bindings.filter(item => item.state === 'ready') if (bindingId !== null) { desktopAssert(bindingId.length <= 100 && /^[a-zA-Z0-9_-]+$/.test(bindingId), '规则编号无效') const binding = ready.find(item => item.id === bindingId) desktopAssert(binding, '此店铺和品类尚未配置规则', 404, 'rules_unavailable') const selected = scopedCatalog(binding!) return { revision: catalog.revision, contentHash: contentHash(selected), catalog: selected } } return { revision: catalog.revision, categories: catalog.categories.map(({ id, name }) => ({ id, name })), items: ready.map(binding => { const shop = catalog.shops.find(item => item.id === binding.shopId)! const category = catalog.categories.find(item => item.id === binding.categoryId)! return { id: binding.id, shopId: shop.id, projectBrandId: shop.id, brandId: shop.brandId, categoryId: category.id, shopName: shop.name, categoryName: category.name, label: `${shop.name} · ${category.name}`, version: binding.revision, contentHash: contentHash(scopedCatalog(binding)) } }) } }