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

scriptype / writ-cms / 26382630443

25 May 2026 04:06AM UTC coverage: 37.588% (-0.05%) from 37.637%
26382630443

push

github

scriptype
Sanitize filename when creating post

- Use filenamify package to strip illegal characters from filename

- Use unused-filename package to avoid existing filename conflict

- If one of the above happened to a file, use title override in the
frontmatter to preserve user's input

- Wrap that title value in the frontmatter with quotes because
front-matter package does not handle character edge-cases like a colon
in a value. Check gray-matter

- Discovery: overriding the title of a post does not seem to affect slug

645 of 3779 branches covered (17.07%)

Branch coverage included in aggregate %.

0 of 10 new or added lines in 1 file covered. (0.0%)

1 existing line in 1 file now uncovered.

2235 of 3883 relevant lines covered (57.56%)

1285.9 hits per line

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

0.0
/src/cms/api/models/post.js
1
const { writeFile, mkdir } = require('fs/promises')
×
2
const { join } = require('path')
×
3
const frontMatter = require('front-matter')
×
NEW
4
const { ['default']: filenamify } = require('filenamify')
×
NEW
5
const { unusedFilename } = require('unused-filename')
×
UNCOV
6
const { contentRootPath, omitResolvedLinks, buildFrontMatter } = require('../helpers')
×
7

8
const createPostModel = ({ getSettings, getContentModel }) => {
×
9
  const createPost = async ({
×
10
    taxonomyPath,
11
    title,
12
    content,
13
    extension,
14
    metadata
15
  }) => {
16
    const opts = {
×
17
      taxonomyPath: taxonomyPath || [],
×
18
      title: title || 'Untitled',
×
19
      content: content || '',
×
20
      extension: extension || 'md',
×
21
      metadata: metadata || {}
×
22
    }
23
    const { rootDirectory, contentDirectory } = getSettings()
×
24
    const root = await contentRootPath(rootDirectory, contentDirectory)
×
25

NEW
26
    const sanitizedTitle = filenamify(opts.title)
×
27

NEW
28
    const path = join(...[root].concat(opts.taxonomyPath).concat(sanitizedTitle))
×
NEW
29
    const unusedPath = await unusedFilename(path)
×
30

NEW
31
    const shouldOverrideTitle = (sanitizedTitle !== opts.title) || (unusedPath !== path)
×
NEW
32
    const metadataWithTitle = shouldOverrideTitle ?
×
33
      {
34
        ...opts.metadata,
35
        title: `"${opts.title}"`
36
      } : opts.metadata
37

NEW
38
    const frontMatter = buildFrontMatter(metadataWithTitle)
×
39
    const fileContent = [frontMatter, opts.content].join('\n').trim()
×
40
    try {
×
NEW
41
      await mkdir(unusedPath, { recursive: true })
×
42
    } catch {}
NEW
43
    return writeFile(`${join(unusedPath, 'post')}.${opts.extension}`, fileContent)
×
44
  }
45

46
  return {
×
47
    create: createPost
48
  }
49
}
50

51
module.exports = createPostModel
×
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