1 | const fs = require('fs')
|
2 | const renderSchema = require('./renderSchema')
|
3 |
|
4 | function updateMarkdown(doc, newContent, options = {}) {
|
5 | const includeMarkers = options.includeMarkers !== false
|
6 | const startMarker = options.startMarker || '<!-- START graphql-markdown -->'
|
7 | const endMarker = options.endMarker || '<!-- END graphql-markdown -->'
|
8 | let startIndex = doc.indexOf(startMarker)
|
9 | let endIndex = doc.lastIndexOf(endMarker)
|
10 | if (startIndex !== -1 && endIndex !== -1 && startIndex < endIndex) {
|
11 | if (includeMarkers) {
|
12 | startIndex += startMarker.length
|
13 | } else {
|
14 | endIndex += endMarker.length
|
15 | }
|
16 | return doc.slice(0, startIndex) + newContent + doc.slice(endIndex)
|
17 | } else if (startIndex === -1) {
|
18 | throw new Error(`Start marker not found: ${startMarker}`)
|
19 | } else if (endIndex === -1) {
|
20 | throw new Error(`End marker not found: ${endMarker}`)
|
21 | } else {
|
22 | throw new Error('Start marker must precede end marker.')
|
23 | }
|
24 | }
|
25 |
|
26 | function updateSchema(path, schema, options) {
|
27 | return new Promise((resolve, reject) => {
|
28 | fs.readFile(path, 'utf8', (err, doc) => {
|
29 | if (err) {
|
30 | if (err.code === 'ENOENT') {
|
31 | doc = ''
|
32 | } else {
|
33 | return reject(err)
|
34 | }
|
35 | }
|
36 | let newContent = ''
|
37 | const printer = (line) => {
|
38 | newContent += `${line}\n`
|
39 | }
|
40 | renderSchema(schema, Object.assign({}, options, { printer }))
|
41 | if (!doc.trim()) {
|
42 | doc = '<!-- START graphql-markdown -->\n<!-- END graphql-markdown -->\n'
|
43 | }
|
44 | let newDoc = doc
|
45 | try {
|
46 | newDoc = updateMarkdown(doc, `\n\n${newContent}\n`)
|
47 | } catch (err) {
|
48 | return reject(err)
|
49 | }
|
50 | fs.writeFile(path, newDoc, 'utf8', (err) => {
|
51 | if (err) {
|
52 | return reject(err)
|
53 | }
|
54 | resolve()
|
55 | })
|
56 | })
|
57 | })
|
58 | }
|
59 |
|
60 | module.exports = updateSchema
|