• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

scriptype / writ-cms / 14117345091

27 Mar 2025 09:48PM UTC coverage: 77.435% (-3.8%) from 81.25%
14117345091

push

github

scriptype
[CM2] Build with CM2 + rendering2

- Turn compiler into a class
- Inject dependencies into compiler based on the temporary compilerVersion setting
- Create a FileSystemParser class and put it under a /lib folder alongside a
  fileSystemHelpers module and delete the compiler/fileSystem. The
  FileSystemParser's settings and debugLog dependencies are also injected
  (tryin something...)
- Update fileSystem's tests to reflect the changes
- Fix forgotten category assumption in attachment permalink
- Fix various small mistakes
- Bring back support for foldered subpages
- Partial preferences when rendering pages should be contemplated more
- Should try a single rendering that works for all kinds of contentModels

426 of 647 branches covered (65.84%)

Branch coverage included in aggregate %.

68 of 79 new or added lines in 8 files covered. (86.08%)

2182 of 2721 relevant lines covered (80.19%)

227.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.56
/src/lib/FileSystemParser.js
1
const { stat, readdir } = require('fs/promises')
6✔
2
const { join, relative, resolve, extname } = require('path')
6✔
3
const { readFileContent, isDirectory } = require('./fileSystemHelpers')
6✔
4

5
module.exports = class FileSystemParser {
6✔
6
  static isTextFile(extension) {
7
    const acceptedExtensions = [
240✔
8
      'txt',
9
      'md',
10
      'markdown',
11
      'hbs',
12
      'handlebars',
13
      'html',
14
      'xhtml',
15
      'htm',
16
      'rtf',
17
      'rtfd',
18
      'json',
19
      'srt'
20
    ]
21
    return new RegExp(`\.(${acceptedExtensions.join('|')})`, 'i').test(extension)
240✔
22
  }
23

24
  static lookBack(path, depth) {
25
    return resolve(path, ...Array(depth).fill('..'))
366✔
26
  }
27

28
  static async contentRoot(rootDirectory, contentDirectory) {
29
    if (!rootDirectory) {
186!
NEW
30
      throw new Error('rootDirectory is a required parameter')
×
31
    }
32
    try {
186✔
33
      await stat(join(rootDirectory, contentDirectory))
186✔
34
      return join(rootDirectory, contentDirectory)
6✔
35
    } catch (ENOENT) {
36
      return rootDirectory
180✔
37
    }
38
  }
39

40
  constructor(fileSystemParserSettings, logger) {
41
    this.rootDirectory = fileSystemParserSettings.rootDirectory
186✔
42
    this.contentDirectory = fileSystemParserSettings.contentDirectory
186✔
43
    this.ignorePattern = fileSystemParserSettings.IGNORE_PATHS_REG_EXP
186✔
44
    this.logger = logger
186✔
45
  }
46

47
  shouldIncludePath(path) {
48
    return (
906✔
49
      !path.startsWith('_') &&
2,538✔
50
      !path.startsWith('.') &&
51
      !path.match(this.ignorePattern)
52
    )
53
  }
54

55
  async parse() {
56
    const root = await FileSystemParser.contentRoot(
186✔
57
      this.rootDirectory,
58
      this.contentDirectory
59
    )
60
    this.logger.debug('contentRoot', root)
186✔
61
    return this._parse(root)
186✔
62
  }
63

64
  async _parse(path, depth = 0) {
186✔
65
    this.logger.debug('exploring', path)
282✔
66
    return Promise.all(
282✔
67
      (await readdir(path))
68
      .filter(this.shouldIncludePath.bind(this))
69
      .map(async fileName => {
70
        const accumulatedPath = join(path, fileName)
336✔
71
        const rootPath = FileSystemParser.lookBack(accumulatedPath, depth + 1)
336✔
72
        const { birthtime } = await stat(accumulatedPath)
336✔
73
        const baseProperties = {
336✔
74
          name: fileName,
75
          path: relative(rootPath, accumulatedPath),
76
          absolutePath: accumulatedPath,
77
          stats: { birthtime },
78
          depth,
79
        }
80
        if (await isDirectory(accumulatedPath)) {
336✔
81
          return {
96✔
82
            ...baseProperties,
83
            children: await this._parse(accumulatedPath, depth + 1)
84
          }
85
        }
86
        const extension = extname(fileName)
240✔
87
        const fileProperties = {
240✔
88
          ...baseProperties,
89
          extension,
90
        }
91
        if (FileSystemParser.isTextFile(extension)) {
240✔
92
          const content = await readFileContent(accumulatedPath)
210✔
93
          return {
210✔
94
            ...fileProperties,
95
            content
96
          }
97
        } else {
98
          return fileProperties
30✔
99
        }
100
      })
101
    )
102
  }
103
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc