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

scriptype / writ-cms / 27566699002

15 Jun 2026 06:13PM UTC coverage: 58.035% (-0.8%) from 58.791%
27566699002

push

github

scriptype
Implement basic page update

Use 'update' over 'edit'

647 of 1102 branches covered (58.71%)

Branch coverage included in aggregate %.

0 of 44 new or added lines in 6 files covered. (0.0%)

2 existing lines in 2 files now uncovered.

2242 of 3876 relevant lines covered (57.84%)

1679.89 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, rename, rm } = require('fs/promises')
×
2
const { join, dirname, basename } = require('path')
×
3
const matter = require('gray-matter')
×
4
const { ['default']: filenamify } = require('filenamify')
×
5
const { unusedFilename } = require('unused-filename')
×
6
const { contentRootPath } = require('../helpers')
×
7

8
const replaceFilename = (oldAbsolutePath, newAbsolutePath) => {
×
9
  return join(
×
10
    dirname(oldAbsolutePath),
11
    basename(newAbsolutePath)
12
  )
13
}
14

15
const createPostModel = ({ getSettings, getContentModel }) => {
×
16
  const createPost = async ({
×
17
    taxonomyPath,
18
    title,
19
    content,
20
    excerpt,
21
    extension,
22
    metadata
23
  }) => {
24
    const opts = {
×
25
      taxonomyPath: taxonomyPath || [],
×
26
      title: title || 'Untitled',
×
27
      content: content || '',
×
28
      excerpt: excerpt || '',
×
29
      extension: extension || '.md',
×
30
      metadata: metadata || {}
×
31
    }
32
    const { rootDirectory, contentDirectory } = getSettings()
×
33
    const root = await contentRootPath(rootDirectory, contentDirectory)
×
34

35
    const sanitizedTitle = filenamify(opts.title)
×
36

37
    const path = join(...[root].concat(opts.taxonomyPath).concat(sanitizedTitle))
×
38
    const unusedPath = await unusedFilename(path)
×
39

40
    const shouldOverrideTitle = (sanitizedTitle !== opts.title) || (unusedPath !== path)
×
41
    const metadataWithTitle = shouldOverrideTitle ?
×
42
      {
43
        ...opts.metadata,
44
        title: `${opts.title}`
45
      } : opts.metadata
46

47
    const fileContent = matter.stringify({
×
48
      data: metadataWithTitle,
49
      content: opts.content,
50
      excerpt: opts.excerpt
51
    })
52
    try {
×
53
      await mkdir(unusedPath, { recursive: true })
×
54
    } catch {}
55
    return writeFile(`${join(unusedPath, 'post')}${opts.extension}`, fileContent)
×
56
  }
57

NEW
58
  const updatePost = async ({
×
59
    path,
60
    title,
61
    content,
62
    excerpt,
63
    extension,
64
    metadata
65
  }) => {
66
    if (!path) {
×
67
      throw new Error('path is required')
×
68
    }
69

70
    const opts = {
×
71
      title: title || 'Untitled',
×
72
      content: content || '',
×
73
      excerpt: excerpt || '',
×
74
      extension: extension || '',
×
75
      metadata: metadata || {}
×
76
    }
77

78
    const collectionName = path.split('/')[0]
×
79
    const collection = getContentModel().subtree.collections.find(c => c.name === collectionName)
×
80
    const post = collection.subtree.posts.find(p => p.path === path)
×
81

82

83
    const isFoldered = !post.extension
×
84
    const isTitleDifferent = opts.title !== post.title
×
85
    let absolutePath = post.absolutePath
×
86
    let isPathDifferentThanTitle
87

88
    if (isTitleDifferent) {
×
89
      const sanitizedTitle = filenamify(opts.title)
×
90
      const sanitizedPath = replaceFilename(post.absolutePath, sanitizedTitle)
×
91
      const unusedPath = await unusedFilename(sanitizedPath)
×
92

93
      if (isFoldered) {
×
94
        await rename(post.absolutePath, unusedPath)
×
95
      } else {
96
        await rm(post.absolutePath)
×
97
      }
98

99
      isPathDifferentThanTitle = (sanitizedTitle !== opts.title) || (unusedPath !== sanitizedPath)
×
100
      absolutePath = isFoldered ? unusedPath : `${unusedPath}${opts.extension || post.extension}`
×
101
    }
102

103
    const metadataWithTitle = isPathDifferentThanTitle ? {
×
104
      ...opts.metadata,
105
      title: `${opts.title}`
106
    } : metadata
107

108
    const fileContent = matter.stringify({
×
109
      data: metadataWithTitle,
110
      content: opts.content,
111
      excerpt: opts.excerpt
112
    })
113

114
    const targetPath = isFoldered ?
×
115
      join(absolutePath, post.indexFile.name) :
116
      absolutePath
117

118
    return writeFile(targetPath, fileContent)
×
119
  }
120

121
  return {
×
122
    create: createPost,
123
    update: updatePost
124
  }
125
}
126

127
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