-
Notifications
You must be signed in to change notification settings - Fork 1
/
doc-generator.js
127 lines (107 loc) · 3.44 KB
/
doc-generator.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
const glob = require('glob');
const fs = require('fs');
const path = require('path');
const graphqlRoot = path.resolve(__dirname, '../../graphql');
glob('../../graphql/**/*.graphql', (er, files) => {
const structures = files
.filter((f) => !/fragment/.test(f))
.map(info)
.reduce((c, t) => {
return Object.assign({}, c, { [t.dir]: (c[t.dir] || []).concat(t) });
}, {});
const title = `# API Documentation
Welcome to the API Documentation for the Alpaca Travel GraphQL JavaScript SDK
for use with React-Query.
- See [Installation and Getting Started](https://alpacatravel.github.io/graph-sdk/packages/react-query/)
`;
const footer = ``;
const sections = Object.keys(structures).map((key) => section(key, structures));
// Table of contents
const doc = [
title,
sections
.filter((sect) => sect.parent[0] === null)
.map((s) => {
const sectionStart = `## ${s.title}\n\n${s.toc}`;
const sectionMiddle = sections.reduce((c, sect) => {
if (sect.parent[0] === s.key) {
return c.concat(`\n\n### ${sect.title}\n\n${sect.toc}`);
}
return c;
}, []);
const sectionDoc = [sectionStart, ...sectionMiddle].join('');
return sectionDoc;
})
.join('\n\n'),
footer,
].join('\n\n');
fs.writeFileSync(path.resolve(__dirname, './api.md'), doc);
});
function section(key, structures) {
const [parent, parentText, parentLink] = (() => {
const first = structures[key][0];
const isParentDifferent = first.dirParent !== first.dir;
if (!isParentDifferent) {
return [null, 'View other SDK Capabilities', '/graphql'];
}
return [
first.dirParent,
`View other ${first.dirParent} SDK capabilities`,
`/graphql/${first.dirParent}`,
];
})();
// Links
return {
key: key,
title: formatString(key),
toc: structures[key]
.map((p) => `- **[${p.title}](${p.link})**\n ${p.comment.trim()}`)
.join('\n'),
parent: [parent, parentText, parentLink],
};
}
function info(input) {
const minimal = input.replace('../../graphql/', '');
// Split out title
const [dir, file] = rsplit(minimal);
// Create a title
// Target the comments at the start of the graphql query
const contents = fs.readFileSync(path.resolve(__dirname, input), 'utf-8');
const [pre] = contents.split(/(query|mutation) (\w+) ?{/);
const isQuery = /\nquery /.test(contents);
const comment = pre
.replace(/#import.+\n/g, '')
.replace(/\n/g, '')
.replace(/# /g, ' ')
.replace(/\..+/, '');
const title = `use${camelize(file.replace(/.graphql/, ''))}${isQuery ? 'Query' : 'Mutation'}`;
const link = `https://alpacatravel.github.io/graph-sdk/packages/react-query/docs/modules.html#${title}`;
return {
dirParent: dir[0],
dir: dir.join('/'),
title,
path: minimal,
comment,
link,
};
}
function formatString(string) {
switch (string.toLowerCase()) {
case 'place/atdw':
return 'Place Provider: Australian Tourism Data Warehouse';
default:
break;
}
return string.split('/').map(upperCaseFirst).join(' ');
}
function upperCaseFirst(input) {
return input.charAt(0).toUpperCase() + input.slice(1);
}
function rsplit(input) {
const split = input.split('/');
return [split.slice(0, -1), split.slice(-1)[0]];
}
const camelize = (s) => {
const string = s.replace(/-./g, (x) => x.toUpperCase()[1]);
return string.charAt(0).toUpperCase() + string.slice(1);
};