'use strict'; // AssetCategoryManager is now a thin facade over src/registry/assetResolver. // The public surface (getCategory / listCategories / hasCategory / searchCategories) // is preserved so existing consumers (src/menu/asset.js, src/helper/assetUtils.js) // don't need to change in this phase. New code should use assetResolver directly. const { assetResolver } = require('../../src/registry'); class AssetCategoryManager { // relPath is retained for signature compatibility with the prior on-disk // implementation; it is unused now — the resolver owns file locations. constructor(/* relPath = '.' */) {} getCategory(softwareType) { if (!softwareType) { throw new Error('softwareType is required'); } const data = assetResolver.resolve('menu', softwareType); if (!data) { throw new Error(`Asset data '${softwareType}' not found in menu namespace`); } return data; } hasCategory(softwareType) { if (!softwareType) return false; return assetResolver.resolve('menu', softwareType) != null; } listCategories({ withMeta = false } = {}) { // The resolver indexes each menu file under BOTH its inner softwareType // and its filename slug — those may differ. Dedupe by payload identity // so we return one entry per source file. const seen = new Set(); const out = []; for (const key of assetResolver.list('menu')) { const data = assetResolver.resolve('menu', key); if (!data || seen.has(data)) continue; seen.add(data); const softwareType = data.softwareType || key; if (withMeta) { out.push({ softwareType, label: data.label || softwareType, file: `${softwareType}.json`, }); } else { out.push(softwareType); } } return out; } searchCategories(query) { const term = (query || '').trim().toLowerCase(); if (!term) return []; return this.listCategories({ withMeta: true }).filter( ({ softwareType, label }) => softwareType.toLowerCase().includes(term) || (label || '').toLowerCase().includes(term), ); } clearCache() { // Caches live in the resolver namespaces. Force-refresh menu. // refresh() is async but the legacy contract here is sync — // fire-and-forget; the next resolve() lazily warms in the worst case. assetResolver.refresh('menu').catch(() => {}); } } const assetCategoryManager = new AssetCategoryManager(); module.exports = { AssetCategoryManager, assetCategoryManager, getCategory: (softwareType) => assetCategoryManager.getCategory(softwareType), listCategories: (options) => assetCategoryManager.listCategories(options), searchCategories: (query) => assetCategoryManager.searchCategories(query), hasCategory: (softwareType) => assetCategoryManager.hasCategory(softwareType), clearCache: () => assetCategoryManager.clearCache(), };