1 | var _ = require('lodash');
|
2 | var path = require('path');
|
3 | var semver = require('semver');
|
4 |
|
5 |
|
6 | var Filter = require('./filter');
|
7 | var Parser = require('./parser');
|
8 | var Worker = require('./worker');
|
9 |
|
10 | var FileError = require('./errors/file_error');
|
11 | var ParserError = require('./errors/parser_error');
|
12 | var WorkerError = require('./errors/worker_error');
|
13 |
|
14 |
|
15 | var SPECIFICATION_VERSION = '0.2.0';
|
16 |
|
17 | var defaults = {
|
18 | excludeFilters: [],
|
19 | includeFilters: [ '.*\\.(clj|coffee|cs|dart|erl|go|java|js|php?|py|rb|ts|pm)$' ],
|
20 |
|
21 | src: path.join(__dirname, '../example/'),
|
22 |
|
23 | filters: {},
|
24 | languages: {},
|
25 | parsers: {},
|
26 | workers: {}
|
27 | };
|
28 |
|
29 | var app = {
|
30 | options : {},
|
31 | log : logger,
|
32 | generator : {},
|
33 | packageInfos: {},
|
34 | markdown : false,
|
35 | filters: {
|
36 | apierror : './filters/api_error.js',
|
37 | apiheader : './filters/api_header.js',
|
38 | apiparam : './filters/api_param.js',
|
39 | apisuccess : './filters/api_success.js'
|
40 | },
|
41 | languages: {
|
42 | '.clj' : './languages/clj.js',
|
43 | '.coffee' : './languages/coffee.js',
|
44 | '.erl' : './languages/erl.js',
|
45 | '.pm' : './languages/pm.js',
|
46 | '.py' : './languages/py.js',
|
47 | '.rb' : './languages/rb.js',
|
48 | 'default' : './languages/default.js'
|
49 | },
|
50 | parsers: {
|
51 | api : './parsers/api.js',
|
52 | apidefine : './parsers/api_define.js',
|
53 | apidefineerrorstructure : './parsers/api_define_error_structure.js',
|
54 | apidefineheaderstructure : './parsers/api_define_header_structure.js',
|
55 | apidefinepermission : './parsers/api_define_permission.js',
|
56 | apidefinestructure : './parsers/api_define_structure.js',
|
57 | apidefinesuccessstructure: './parsers/api_define_success_structure.js',
|
58 | apigroupdescription : './parsers/api_group_description.js',
|
59 | apidescription : './parsers/api_description.js',
|
60 | apierror : './parsers/api_error.js',
|
61 | apierrorexample : './parsers/api_error_example.js',
|
62 | apierrorstructure : './parsers/api_error_structure.js',
|
63 | apierrortitle : './parsers/api_error_title.js',
|
64 | apiexample : './parsers/api_example.js',
|
65 | apiheader : './parsers/api_header.js',
|
66 | apiheaderexample : './parsers/api_header_example.js',
|
67 | apiheaderstructure : './parsers/api_header_structure.js',
|
68 | apiheadertitle : './parsers/api_header_title.js',
|
69 | apigroup : './parsers/api_group.js',
|
70 | apiname : './parsers/api_name.js',
|
71 | apiparam : './parsers/api_param.js',
|
72 | apiparamexample : './parsers/api_param_example.js',
|
73 | apiparamtitle : './parsers/api_param_title.js',
|
74 | apipermission : './parsers/api_permission.js',
|
75 | apistructure : './parsers/api_structure.js',
|
76 | apisuccess : './parsers/api_success.js',
|
77 | apisuccessexample : './parsers/api_success_example.js',
|
78 | apisuccessstructure : './parsers/api_success_structure.js',
|
79 | apisuccesstitle : './parsers/api_success_title.js',
|
80 | apiuse : './parsers/api_use.js',
|
81 | apiversion : './parsers/api_version.js',
|
82 | apisamplerequest : './parsers/api_sample_request.js'
|
83 | },
|
84 | workers: {
|
85 | apierrorstructure : './workers/api_error_structure.js',
|
86 | apierrortitle : './workers/api_error_title.js',
|
87 | apigroup : './workers/api_group.js',
|
88 | apiheaderstructure : './workers/api_header_structure.js',
|
89 | apiheadertitle : './workers/api_header_title.js',
|
90 | apiname : './workers/api_name.js',
|
91 | apiparamtitle : './workers/api_param_title.js',
|
92 | apipermission : './workers/api_permission.js',
|
93 | apisamplerequest : './workers/api_sample_request.js',
|
94 | apistructure : './workers/api_structure.js',
|
95 | apisuccessstructure : './workers/api_success_structure.js',
|
96 | apisuccesstitle : './workers/api_success_title.js',
|
97 | apiuse : './workers/api_use.js',
|
98 |
|
99 | deprecatedApiErrorTitle : './workers/deprecated_api_error_title.js',
|
100 | deprecatedApiHeaderTitle : './workers/deprecated_api_header_title.js',
|
101 | deprecatedApiParamTitle : './workers/deprecated_api_param_title.js',
|
102 | deprecatedApiSuccessTitle: './workers/deprecated_api_success_title.js'
|
103 | }
|
104 | };
|
105 |
|
106 | var defaultGenerator = {
|
107 | name : 'apidoc',
|
108 | time : new Date(),
|
109 | url : 'http://apidocjs.com',
|
110 | version: '0.0.0'
|
111 | };
|
112 |
|
113 |
|
114 | var defaultPackageInfos = {
|
115 | description: '',
|
116 | name : '',
|
117 | sampleUrl : false,
|
118 | version : '0.0.0'
|
119 | };
|
120 |
|
121 |
|
122 | var logger = {
|
123 | debug : function() { console.log(arguments); },
|
124 | verbose: function() { console.log(arguments); },
|
125 | info : function() { console.log(arguments); },
|
126 | warn : function() { console.log(arguments); },
|
127 | error : function() { console.log(arguments); }
|
128 | };
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 | function getSpecificationVersion() {
|
136 | return SPECIFICATION_VERSION;
|
137 | }
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 | function parse(options) {
|
152 | _.defaults(options, defaults);
|
153 |
|
154 |
|
155 | app.filters = _.defaults(options.filters, app.filters);
|
156 | app.languages = _.defaults(options.languages, app.languages);
|
157 | app.parsers = _.defaults(options.parsers, app.parsers);
|
158 | app.workers = _.defaults(options.workers, app.workers);
|
159 |
|
160 |
|
161 | app.options = options;
|
162 |
|
163 |
|
164 | _.defaults(app.generator, defaultGenerator);
|
165 |
|
166 |
|
167 | _.defaults(app.packageInfos, defaultPackageInfos);
|
168 |
|
169 | var parsedFiles = [];
|
170 | var parsedFilenames = [];
|
171 |
|
172 | try {
|
173 | var parser = new Parser(app);
|
174 | var worker = new Worker(app);
|
175 | var filter = new Filter(app);
|
176 |
|
177 |
|
178 |
|
179 | if (options.src instanceof Array) {
|
180 | options.src.forEach(function(folder) {
|
181 |
|
182 |
|
183 | var folderOptions = options;
|
184 | folderOptions.src = path.join(folder, './');
|
185 | parser.parseFiles(folderOptions, parsedFiles, parsedFilenames);
|
186 | });
|
187 | }
|
188 | else {
|
189 |
|
190 | options.src = path.join(options.src, './');
|
191 | parser.parseFiles(options, parsedFiles, parsedFilenames);
|
192 | }
|
193 |
|
194 | if (parsedFiles.length > 0) {
|
195 |
|
196 | worker.process(parsedFiles, parsedFilenames, app.packageInfos);
|
197 |
|
198 |
|
199 | var blocks = filter.process(parsedFiles, parsedFilenames);
|
200 |
|
201 |
|
202 | blocks.sort(function(a, b) {
|
203 | var nameA = a.group + a.name;
|
204 | var nameB = b.group + b.name;
|
205 | if (nameA === nameB) {
|
206 | if (a.version === b.version)
|
207 | return 0;
|
208 | return (semver.gte(a.version, b.version)) ? -1 : 1;
|
209 | }
|
210 | return (nameA < nameB) ? -1 : 1;
|
211 | });
|
212 |
|
213 |
|
214 | app.packageInfos.apidoc = SPECIFICATION_VERSION;
|
215 |
|
216 |
|
217 | app.packageInfos.generator = app.generator;
|
218 |
|
219 |
|
220 | var apiData = JSON.stringify(blocks, null, 2);
|
221 | apiData = apiData.replace(/(\r\n|\n|\r)/g, '\r\n');
|
222 |
|
223 |
|
224 | var apiProject = JSON.stringify(app.packageInfos, null, 2);
|
225 | apiProject = apiProject.replace(/(\r\n|\n|\r)/g, '\r\n');
|
226 |
|
227 | return {
|
228 | data : apiData,
|
229 | project: apiProject
|
230 | };
|
231 | }
|
232 | return true;
|
233 | } catch(e) {
|
234 |
|
235 | var extra;
|
236 | var meta = {};
|
237 | if (e instanceof FileError) {
|
238 | meta = { 'Path': e.path };
|
239 | app.log.error(e.message, meta);
|
240 | } else if (e instanceof ParserError) {
|
241 | extra = e.extra;
|
242 | if (e.source)
|
243 | extra.unshift({ 'Source': e.source });
|
244 | if (e.element)
|
245 | extra.unshift({ 'Element': '@' + e.element });
|
246 | if (e.block)
|
247 | extra.unshift({ 'Block': e.block });
|
248 | if (e.file)
|
249 | extra.unshift({ 'File': e.file });
|
250 |
|
251 | extra.forEach(function(obj) {
|
252 | var key = Object.keys(obj)[0];
|
253 | meta[key] = obj[key];
|
254 | });
|
255 |
|
256 | app.log.error(e.message, meta);
|
257 | }
|
258 | else if (e instanceof WorkerError) {
|
259 | extra = e.extra;
|
260 | if (e.definition)
|
261 | extra.push({ 'Definition': e.definition });
|
262 | if (e.example)
|
263 | extra.push({ 'Example': e.example });
|
264 | extra.unshift({ 'Element': '@' + e.element });
|
265 | extra.unshift({ 'Block': e.block });
|
266 | extra.unshift({ 'File': e.file });
|
267 |
|
268 | extra.forEach(function(obj) {
|
269 | var key = Object.keys(obj)[0];
|
270 | meta[key] = obj[key];
|
271 | });
|
272 |
|
273 | app.log.error(e.message, meta);
|
274 | }
|
275 | else {
|
276 | app.log.error(e.message);
|
277 | if (e.stack)
|
278 | app.log.debug(e.stack);
|
279 | }
|
280 | return false;
|
281 | }
|
282 | }
|
283 |
|
284 |
|
285 |
|
286 |
|
287 |
|
288 |
|
289 |
|
290 |
|
291 |
|
292 |
|
293 | function setGeneratorInfos(generator) {
|
294 | app.generator = generator;
|
295 | }
|
296 |
|
297 |
|
298 |
|
299 |
|
300 |
|
301 |
|
302 |
|
303 |
|
304 |
|
305 |
|
306 |
|
307 |
|
308 | function setLogger(logger) {
|
309 | app.log = logger;
|
310 | }
|
311 |
|
312 |
|
313 |
|
314 |
|
315 |
|
316 |
|
317 | function setMarkdownParser(markdown) {
|
318 | app.markdown = markdown;
|
319 | }
|
320 |
|
321 |
|
322 |
|
323 |
|
324 |
|
325 |
|
326 |
|
327 |
|
328 |
|
329 |
|
330 | function setPackageInfos(packageInfos) {
|
331 | app.packageInfos = packageInfos;
|
332 | }
|
333 |
|
334 | module.exports = {
|
335 | getSpecificationVersion: getSpecificationVersion,
|
336 | parse : parse,
|
337 | setGeneratorInfos : setGeneratorInfos,
|
338 | setLogger : setLogger,
|
339 | setMarkdownParser : setMarkdownParser,
|
340 | setPackageInfos : setPackageInfos
|
341 | };
|