UNPKG

5.81 kBPlain TextView Raw
1#!/usr/bin/env node
2
3'use strict';
4
5// Ignore unused `heroku` var that's called in `eval` below
6// jshint -W098
7
8var assert = require('assert');
9var fs = require('fs');
10var Heroku = require('../lib/heroku');
11var heroku = new Heroku({});
12var inflection = require('inflection');
13var path = require('path');
14var resources = require('../lib/schema').definitions;
15var resource, resourceName;
16
17for (resourceName in resources) {
18 resource = resources[resourceName];
19 createDocumentation(resourceName, resource);
20}
21
22function createDocumentation(resourceName, resource) {
23 var file = createFile(resourceName);
24
25 process.stdout.write('\nBuilding docs for ' + resourceName + ':\n');
26
27 fs.appendFileSync(file, '# ' + resourceName + '\n\n');
28 if (resource.description) fs.appendFileSync(file, resource.description + '\n\n');
29
30 addActions(file, resource.links);
31 addAttributes(file, resource.attributes);
32}
33
34function getName(name) {
35 name = name.toLowerCase();
36 name = inflection.dasherize(name).replace(/-/g, '_');
37 name = inflection.camelize(name, true);
38 return name;
39}
40
41function createFile(resourceName) {
42 var fileName = getName(resourceName);
43 var file = path.join(__dirname, '../docs/' + fileName + '.md');
44 fs.writeFileSync(file, '');
45 return file;
46}
47
48function addActions(file, actions) {
49 var action, actionName, i;
50
51 process.stdout.write(' Building actions:');
52 fs.appendFileSync(file, '## Actions\n\n');
53
54 for (i in actions) {
55 action = actions[i];
56 actionName = action.title;
57
58 process.stdout.write('\n ' + actionName);
59 addAction(file, actionName, action);
60 }
61}
62
63function addAction(file, actionName, action) {
64 fs.appendFileSync(file, '### `' + getName(actionName) + '`\n\n');
65 fs.appendFileSync(file, '`' + getFunctionCall(actionName, action) + '`\n\n');
66 fs.appendFileSync(file, 'Method | ');
67 fs.appendFileSync(file, 'Path\n');
68 fs.appendFileSync(file, '--- | ');
69 fs.appendFileSync(file, '---\n');
70 fs.appendFileSync(file, action.method + ' | ');
71 fs.appendFileSync(file, prettifyHref(action.href) + '\n\n');
72 addActionAttributes(file, action);
73
74 checkAction(actionName, action);
75}
76
77function getFunctionCall(actionName, action) {
78 var path = action.href.split(/\//);
79 var segments = path.slice(1, path.length);
80 var functionCall = 'heroku';
81 var i, segment;
82
83 for (i = 0; i < segments.length; i ++) {
84 segment = segments[i];
85
86 if (segment.match(/{[^}]+}/)) {
87 continue;
88 } else {
89 functionCall += '.' + getName(segment);
90
91 if (segments[i + 1] && segments[i + 1].match(/{[^}]+}/)) {
92 functionCall += '(' + prettifySegment(segments[i + 1]) + ')';
93 } else {
94 functionCall += '()';
95 }
96 }
97 }
98
99 functionCall += '.' + getName(actionName) + '(';
100
101 if (['PATCH', 'POST', 'PUT'].indexOf(action.method) > -1) {
102 functionCall += '{attributes}, ';
103 }
104
105 functionCall += '{callback});';
106
107 return functionCall;
108}
109
110function prettifyHref(href) {
111 var segments = href.split(/\//);
112 segments = segments.slice(1, segments.length);
113 segments = segments.map(prettifySegment);
114 href = '/' + segments.join('/');
115 return href;
116}
117
118function prettifySegment(segment) {
119 var unescaped = unescape(segment);
120 var identities;
121
122 if (unescaped === segment) {
123 return segment;
124 }
125
126 identities = getIdentitiesFromParam(unescaped);
127 return '{' + identities[0] + '_' + identities.slice(1, identities.length).sort().join('_or_') + '}';
128}
129
130function getIdentitiesFromParam(param) {
131 var identities = param.replace(/[{}()#]/g, '').split("/");
132 var resourceName;
133
134 identities = identities.slice(1, identities.length);
135 identities = resources[identities[1]].definitions.identity;
136 identities = identities.anyOf || [identities];
137
138 identities = identities.map(function (identity) {
139 var parts = identity.$ref.split('/');
140 resourceName = parts[2];
141 return parts.slice(-1)[0];
142 });
143
144 identities.unshift(resourceName);
145
146 return identities;
147}
148
149function addActionAttributes(file, action) {
150 if (!action.attributes) return;
151
152 addActionAttributeGroup(file, action.attributes.optional, 'Optional');
153 fs.appendFileSync(file, '\n');
154
155 addActionAttributeGroup(file, action.attributes.required, 'Required');
156 fs.appendFileSync(file, '\n');
157}
158
159function addActionAttributeGroup(file, attributes, type) {
160 if (!attributes) return;
161
162 fs.appendFileSync(file, '#### ' + type + ' Attributes\n\n');
163
164 attributes.forEach(function (attribute) {
165 fs.appendFileSync(file, '- ' + attribute + '\n');
166 });
167}
168
169function addAttributes(file, attributes) {
170 var attributeName, attribute;
171
172 if (!attributes) return;
173
174 process.stdout.write('\n Building attributes\n');
175 fs.appendFileSync(file, '## Attributes\n\n');
176
177 for (attributeName in attributes) {
178 attribute = attributes[attributeName];
179 addAttribute(file, attributeName, attribute);
180 }
181}
182
183function addAttribute(file, attributeName, attribute) {
184 fs.appendFileSync(file, '### `' + attributeName + '`\n\n');
185
186 fs.appendFileSync(file, '*' + attribute.description + '*\n\n');
187
188 fs.appendFileSync(file, 'Example | ');
189 fs.appendFileSync(file, 'Serialized? | ');
190 fs.appendFileSync(file, 'Type\n');
191 fs.appendFileSync(file, '--- | ');
192 fs.appendFileSync(file, '--- | ');
193 fs.appendFileSync(file, '---\n');
194 fs.appendFileSync(file, '`' + attribute.example + '` | ');
195 fs.appendFileSync(file, attribute.serialized + ' | ');
196 fs.appendFileSync(file, attribute.type + '\n\n');
197}
198
199function checkAction(actionName, action) {
200 // Ignore eval for testing
201 // jshint -W061
202 var functionToTest = getFunctionCall(actionName, action).replace(/{.*}/g, '').slice(0, -3);
203 assert.equal(eval('typeof ' + functionToTest), 'function', functionToTest + ' is not a Function');
204 process.stdout.write(' ' + String.fromCharCode(0x2713));
205}