gongxiangp2/lib/desktop-client/agent-rules.ts

33 lines
2.0 KiB
TypeScript

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)) }
}) }
}