-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathpushDoc.js
113 lines (104 loc) · 3.89 KB
/
pushDoc.js
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
const chalk = require('chalk');
const config = require('config');
const crypto = require('crypto');
const fs = require('fs');
const grayMatter = require('gray-matter');
const path = require('path');
const APIError = require('./apiError');
const { cleanHeaders, handleRes } = require('./fetch');
const fetch = require('./fetch');
const { debug } = require('./logger');
/**
* Reads the contents of the specified Markdown file
* and creates/updates the doc in ReadMe
*
* @param {String} key the project API key
* @param {String} selectedVersion the project version
* @param {Boolean} dryRun boolean indicating dry run mode
* @param {String} filepath path to the Markdown file
* @param {String} type module within ReadMe to update (e.g. docs, changelogs, etc.)
* (file extension must end in `.md` or `.markdown`)
* @returns {Promise<String>} a string containing the result
*/
module.exports = async function pushDoc(key, selectedVersion, dryRun, filepath, type) {
debug(`reading file ${filepath}`);
const file = fs.readFileSync(filepath, 'utf8');
const matter = grayMatter(file);
debug(`frontmatter for ${filepath}: ${JSON.stringify(matter)}`);
// Stripping the subdirectories and markdown extension from the filename and lowercasing to get the default slug.
const slug = matter.data.slug || path.basename(filepath).replace(path.extname(filepath), '').toLowerCase();
const hash = crypto.createHash('sha1').update(file).digest('hex');
function createDoc() {
if (dryRun) {
return `🎭 dry run! This will create '${slug}' with contents from ${filepath} with the following metadata: ${JSON.stringify(
matter.data
)}`;
}
return fetch(`${config.get('host')}/api/v1/${type}`, {
method: 'post',
headers: cleanHeaders(key, {
'x-readme-version': selectedVersion,
'Content-Type': 'application/json',
}),
body: JSON.stringify({
slug,
body: matter.content,
...matter.data,
lastUpdatedHash: hash,
}),
})
.then(res => handleRes(res))
.then(res => `🌱 successfully created '${res.slug}' with contents from ${filepath}`);
}
function updateDoc(existingDoc) {
if (hash === existingDoc.lastUpdatedHash) {
return `${dryRun ? '🎭 dry run! ' : ''}\`${slug}\` ${
dryRun ? 'will not be' : 'was not'
} updated because there were no changes.`;
}
if (dryRun) {
return `🎭 dry run! This will update '${slug}' with contents from ${filepath} with the following metadata: ${JSON.stringify(
matter.data
)}`;
}
return fetch(`${config.get('host')}/api/v1/${type}/${slug}`, {
method: 'put',
headers: cleanHeaders(key, {
'x-readme-version': selectedVersion,
'Content-Type': 'application/json',
}),
body: JSON.stringify(
Object.assign(existingDoc, {
body: matter.content,
...matter.data,
lastUpdatedHash: hash,
})
),
})
.then(res => handleRes(res))
.then(res => `✏️ successfully updated '${res.slug}' with contents from ${filepath}`);
}
return fetch(`${config.get('host')}/api/v1/${type}/${slug}`, {
method: 'get',
headers: cleanHeaders(key, {
'x-readme-version': selectedVersion,
Accept: 'application/json',
}),
})
.then(async res => {
const body = await res.json();
debug(`GET /${type}/:slug API response for ${slug}: ${JSON.stringify(body)}`);
if (!res.ok) {
if (res.status !== 404) return Promise.reject(new APIError(body));
debug(`error retrieving data for ${slug}, creating doc`);
return createDoc(body);
}
debug(`data received for ${slug}, updating doc`);
return updateDoc(body);
})
.catch(err => {
// eslint-disable-next-line no-param-reassign
err.message = `Error uploading ${chalk.underline(filepath)}:\n\n${err.message}`;
throw err;
});
};