All files / src/Layout LayoutManager.ts

73.33% Statements 22/30
50% Branches 5/10
88.88% Functions 8/9
73.33% Lines 22/30

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86          6x               9x 9x 9x             2x             1x 1x   1x             9x 2x     7x 7x         7x 7x 7x       9x       9x             9x       9x       9x       9x       9x      
import fs from 'fs-extra';
import path from 'path';
import { Layout, LayoutConfig, PageNjkAssets } from './Layout.js';
import * as logger from '../utils/logger.js';
 
const FRONTMATTER_NONE_ATTR = 'none';
 
export class LayoutManager {
  private config: LayoutConfig;
  private layoutsRootPath: string;
  private layouts: { [name: string]: Layout };
 
  constructor(config: LayoutConfig) {
    this.config = config;
    this.layoutsRootPath = path.join(config.rootPath, '_markbind', 'layouts');
    this.layouts = {};
  }
 
  /**
   * Flag all layouts for (re)generation when requested
   */
  removeLayouts(): void {
    this.layouts = {};
  }
 
  /**
   * Update layouts which have the provided filePaths as dependencies
   */
  updateLayouts(filePaths: string[]): Promise<void[]> {
    const layoutsToRegenerate = Object.entries(this.layouts)
      .filter(([, layout]) => layout.shouldRegenerate(filePaths));
 
    return Promise.all(layoutsToRegenerate.map(([name, layout]) => {
      this.layouts[name] = new Layout(layout.sourceFilePath, this.config);
      return this.layouts[name].generate();
    }));
  }
 
  generateLayoutIfNeeded(name: string): Promise<void> | undefined {
    if (this.layouts[name]) {
      return this.layouts[name].generatePromise;
    }
 
    const layoutPath = path.join(this.layoutsRootPath, name);
    Iif (!fs.existsSync(layoutPath)) {
      logger.error(`'${name}' layout does not exist`);
      return Promise.resolve();
    }
 
    this.layouts[name] = new Layout(layoutPath, this.config);
    this.layouts[name].generatePromise = this.layouts[name].generate();
    return this.layouts[name].generatePromise;
  }
 
  layoutHasPageNav(name: string): boolean {
    Iif (name === FRONTMATTER_NONE_ATTR) {
      return false;
    }
 
    return !!this.layouts[name] && !!this.layouts[name].layoutPageNavUuid;
  }
 
  combineLayoutWithPage(name: string,
                        pageContent: string,
                        pageNav: string,
                        pageIncludedFiles: Set<string>): string {
    Iif (name === FRONTMATTER_NONE_ATTR) {
      return pageContent;
    }
 
    Iif (!this.layouts[name]) {
      return pageContent;
    }
 
    return this.layouts[name].insertPage(pageContent, pageNav, pageIncludedFiles);
  }
 
  getLayoutPageNjkAssets(name: string): PageNjkAssets | {} {
    Iif (name === FRONTMATTER_NONE_ATTR || !this.layouts[name]) {
      return {};
    }
 
    return this.layouts[name].getPageNjkAssets();
  }
}