UNPKG

@mdfriday/foundry

Version:

The core engine of MDFriday. Convert Markdown and shortcodes into fully themed static sites – Hugo-style, powered by TypeScript.

313 lines 12.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Content = void 0; const _1 = require("./"); const doctree_1 = require("../../../../pkg/doctree"); const fileinfo_1 = require("../vo/fileinfo"); const log_1 = require("../../../../pkg/log"); const paths_1 = require("../../../domain/paths"); // Create a domain-specific logger for content operations const log = (0, log_1.getDomainLogger)('content', { component: 'content' }); class Content { constructor(fs, converter, pageMap) { this.fs = fs; this.converter = converter; this.pageMap = pageMap; } setTemplateSvc(templateSvc) { this.pageMap.pageBuilder.templateSvc = templateSvc; } async renderString(ctx, ...args) { if (args.length < 1 || args.length > 2) { throw new Error("RenderString want 1 or 2 arguments"); } let sidx = 1; if (args.length === 1) { sidx = 0; } else { const firstArg = args[0]; if (typeof firstArg !== 'object' || firstArg === null) { throw new Error("first argument must be a map"); } throw new Error("RenderString not implemented yet"); } const contentToRender = args[sidx]; const contentStr = String(contentToRender); const fmi = this.fs.newFileMetaInfoWithContent(contentStr); const file = (0, fileinfo_1.newFileInfo)(fmi); // For now, return the content directly without caching // TODO: Implement proper caching when cache system is available return contentStr; } async collectPages() { try { await this.process(); await this.assemble(); } catch (error) { throw new Error(`process/assemble: ${error}`); } } async process() { try { const c = new _1.PagesCollector(this.pageMap, this.fs); await c.collect(); } catch (error) { throw error; } } async assemble() { try { await this.pageMap.assemble(); } catch (error) { throw error; } } /** * GetPageSources - exact replica of Go's GetPageSources method */ async getPageSources(page) { let keyPage = page.paths().base(); if (keyPage === "/") { keyPage = ""; } const key = keyPage + "/get-sources-for-page"; return await this.pageMap.getResourcesForPage(page); } /** * GlobalPages - exact replica of Go's GlobalPages method */ async globalPages(langIndex) { return await this.pageMap.getPagesInSection(langIndex, new _1.PageMapQueryPagesInSectionImpl("", "global", true, // recursive true, // includeSelf 0, // index _1.pagePredicates.shouldListGlobal)); } async globalRegularPages() { return await this.pageMap.getPagesInSection(0, new _1.PageMapQueryPagesInSectionImpl("", "global", true, // recursive true, // includeSelf 0, // index (p) => _1.pagePredicates.shouldListGlobal(p) && _1.pagePredicates.kindPage(p))); } /** * WalkPages - exact replica of Go's WalkPages method * TypeScript equivalent of golang/internal/domain/contenthub/entity/walk.go:WalkPages */ async walkPages(langIndex, walker) { try { // Get the page tree for the specified language index // This is equivalent to: tree := ch.PageMap.TreePages.Shape(0, langIndex) const tree = this.pageMap.treePages.shape(0, langIndex); // Create a walker equivalent to Go's NodeShiftTreeWalker const walkHandler = async (key, node) => { if (!node) { return false; } // Equivalent to: ps, found := n.getPage() const [page, found] = node.getPage(); if (!found) { return false; } // Equivalent to: if err := walker(ps); err != nil { return false, err } try { await walker(page); } catch (error) { throw error; } return false; // Continue walking }; // Walk the tree - this mimics the Go version's tree walking await this.walkTree(tree, walkHandler); } catch (error) { log.error(`WalkPages failed for langIndex ${langIndex}:`, error); throw error; } } /** * WalkTaxonomies - exact replica of Go's WalkTaxonomies method * TypeScript equivalent of golang/internal/domain/contenthub/entity/walk.go:WalkTaxonomies */ async walkTaxonomies(langIndex, walker) { try { // Get the page tree for the specified language index const tree = this.pageMap.treePages.shape(0, langIndex); // Get taxonomy views from the page builder's taxonomy service const tc = this.pageMap.pageBuilder.taxonomy; for (const viewName of tc.views) { const key = tc.pluralTreeKey(viewName.plural()); // Create a walker handler for each taxonomy const w = new doctree_1.NodeShiftTreeWalker({ tree: tree, prefix: (0, _1.addTrailingSlash)(key), lockType: doctree_1.LockType.LockTypeRead, handle: async (s, n, match) => { const [p, found] = n.getPage(); if (!found) { return [false, null]; } // Check if this is a term page if (p.kind() === 'term') { const t = p; // TermPage if (!t.term) { return [true, new Error('term is empty')]; } const k = t.term.toLowerCase(); // Walk through taxonomy entries try { await this.pageMap.treeTaxonomyEntries.walkPrefix(doctree_1.LockType.LockTypeRead, (0, _1.addTrailingSlash)(s), (ss, wn) => { const [sp, found] = wn.getPage(); if (!found) { return [false, null]; } // Call the walker function but don't await it here // The promise will be handled by the caller walker(viewName.plural(), k, { weight: () => wn.term.Weight(), ordinal: () => wn.term.Ordinal(), page: () => sp, owner: () => t }).catch(err => { log.error('Error in taxonomy walker:', err); }); return [false, null]; }); return [false, null]; } catch (err) { return [true, err]; } } return [false, null]; } }); await w.walk(); } } catch (error) { throw error; } } /** * Helper method to walk the tree structure * This is a simplified version of Go's NodeShiftTreeWalker.Walk */ async walkTree(tree, handler) { // This is a simplified implementation // In the Go version, this uses a sophisticated tree walker // For now, we'll iterate through available pages try { // Get all available pages using the existing getPagesInSection method // This gets all pages recursively from root, which is equivalent to walking the entire tree const allPages = await this.pageMap.getPagesInSection(0, // langIndex - we'll use the same langIndex from the calling method new _1.PageMapQueryPagesInSectionImpl("", // path - empty string means root "walk", // keyPart true, // recursive - get all pages true, // includeSelf 0, // index () => true // include all pages )); for (let i = 0; i < allPages.length; i++) { const page = allPages[i]; const key = page.paths().path(); // Create a mock node that has getPage method const mockNode = { getPage: () => [page, true] }; await handler(key, mockNode); } } catch (error) { log.error('Error walking tree:', error); throw error; } } /** * GetPageFromPath - TypeScript equivalent of Go's PageFinder.GetPageFromPath * This is the core content domain business logic for finding pages by path */ getPageFromPath(langIndex, path) { try { const pathProcessor = paths_1.PathDomain.createProcessor(); const ps = pathProcessor.parse(paths_1.PATH_CONSTANTS.COMPONENT_FOLDER_CONTENT, path); const tree = this.pageMap.treePages.shape(0, langIndex); // Parse the path - equivalent to Go's paths.Parse(files.ComponentFolderContent, path) // Try exact match first - equivalent to: n := tree.Get(p.Base()) let node = tree.get(ps.base()); if (node) { const [page, found] = node.getPage(); if (found) { return page; } } return null; } catch (error) { log.error(`❌ Content.getPageFromPath error for path "${path}":`, error); return null; } } getPageFromFile(langIndex, file) { try { const tree = this.pageMap.treePages.shape(0, langIndex); let node = tree.get(file.paths().base()); if (node) { const [page, found] = node.getPage(); if (found) { return page; } } return null; } catch (error) { log.error(`❌ Content.getPageFromPath error for path "${file.path()}":`, error); return null; } } async handleChangeFiles(fileMetaInfos) { const affectedPageKeys = []; for (const [filePath, fileMetaInfo] of fileMetaInfos) { try { await this.addOrUpdateFile(fileMetaInfo, affectedPageKeys); } catch (error) { log.error(`Failed to process file change for ${filePath}:`, error); } } return affectedPageKeys; } /** * 添加或更新文件到 PageMap,参考 collectDir 中的实现 */ async addOrUpdateFile(fileMetaInfo, affectedPageKeys) { if (fileMetaInfo.isDir()) { // 目录变更,暂时不处理(在这个阶段我们只关注单个文件) return; } try { // 参考 collectDir 中的实现:为文件创建 FileInfo 并添加到 PageMap const file = (0, fileinfo_1.newFileInfo)(fileMetaInfo); // 获取现有页面的 key(如果存在) const pageKey = file.paths().base(); if (pageKey) { affectedPageKeys.push(pageKey); } // 添加到 PageMap(如果页面已存在会被更新) await this.pageMap.addFi(file); const page = this.getPageFromFile(0, file); if (page && page.pageIdentity) { page.pageIdentity().markStale(); } } catch (error) { log.error(`Failed to add/update file in PageMap: ${fileMetaInfo.fileName()}`, error); throw error; } } } exports.Content = Content; //# sourceMappingURL=content.js.map