All files / src/class/file compiled-file.ts

82.93% Statements 34/41
61.9% Branches 13/21
100% Functions 4/4
88.24% Lines 30/34

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 87 88 89 90 91 92 93 9415x   15x 15x               15x                               80x     80x     80x                   80x 80x 80x   80x 80x   80x       58x   58x 40x   40x 40x       50x 1x 1x   49x   43x 43x       30x 30x 30x 24x   24x 24x                        
import { Resource, Effect } from '@/internal'
import { Encoding } from '@/consts'
import { diffFile } from '@/utils'
import { isNil } from 'ramda'
 
 
export interface CheckOptions {
  showDiff?: boolean
  fold?: boolean
}
 
export class CompiledFile {
  public templatePath: string
 
  public encoding: Encoding
 
  public projectPath: string
 
  private projectContent?: string
 
  public projectFileExisted: boolean
 
  public content: string
 
  public resource: Resource
 
  /** Delete project file */
  public deleted: boolean = false
 
  /** Need to render file */
  public renderable: boolean = true
 
  /** Additional file information that added by handler */
  public addition = {}
 
  constructor(
    templatePath: string,
    content: string,
    encoding: Encoding,
    projectPath: string,
    resource: Resource,
    projectFileExisted: boolean,
  ) {
    this.templatePath = templatePath
    this.projectPath = projectPath
    this.projectFileExisted = projectFileExisted
 
    this.encoding = encoding
    this.content = content
 
    this.resource = resource
  }
 
  public async getProjectContent(): Promise<string> {
    const { projectPath, encoding } = this
 
    if (!isNil(this.projectContent)) return this.projectContent
    Iif (!this.projectFileExisted) throw new Error(`Cannot get content from an unexisted file ${projectPath}.`)
 
    this.projectContent = await Effect.fs.readFile(projectPath, encoding)
    return this.projectContent
  }
 
  public async render(): Promise<void> {
    if (this.deleted) {
      await Effect.fs.remove(this.projectPath)
      return
    }
    if (!this.renderable) return
 
    const { projectPath, content, encoding } = this
    await Effect.fs.writeFile(projectPath, content, encoding)
  }
 
  public async check(options: CheckOptions = {}): Promise<boolean> {
    const { projectPath, deleted, renderable, projectFileExisted } = this
    Iif (deleted && projectFileExisted) throw new Error(`${projectPath}: Should be removed`)
    if (!renderable) return true
    Iif (!projectFileExisted) throw new Error(`${projectPath}: Not exist`)
 
    const projectContent = await this.getProjectContent()
    Eif (this.content === projectContent) return true
 
    if (options.showDiff) {
      const diff = diffFile(this.projectPath, projectContent, this.content, { fold: options.fold })
      throw new Error(diff)
    } else {
      throw new Error(`${projectPath}: Not match template.`)
    }
  }
}
 
export type CompiledFiles = CompiledFile[]