UNPKG

3.36 kBJavaScriptView Raw
1/*
2 * static-api-docs
3 *
4 *
5 * Copyright (c) 2015 Richard Gwozdz
6 * Licensed under the Apache license.
7 */
8
9'use strict';
10
11var fs = require('fs');
12var nunjucks = require('nunjucks');
13var lodash = require('lodash');
14var jsonRefs = require('json-refs');
15
16nunjucks.configure({ autoescape: true });
17
18module.exports = function (grunt) {
19
20
21 grunt.registerMultiTask('static_api_docs', '', function () {
22
23 // Merge task-specific and/or target-specific options with these defaults.
24 var options = this.options({});
25
26
27
28 if(!this.data.hasOwnProperty('src')){
29 grunt.log.warn('No "src" property in target: "' + this.target + '".');
30 return false;
31 }
32 if(!this.data.hasOwnProperty('dest')){
33 grunt.log.warn('No "dest" property in target: "' + this.target + '".');
34 return false;
35 }
36 if (!grunt.file.exists(this.data.src)) {
37 grunt.log.warn('Source file "' + this.data.src + '" not found.');
38 return false;
39 }
40
41 // Swagger JSON source
42 var swaggerJSON = require(process.cwd() + '/' + this.data.src);
43 var apiModel = jsonRefs.resolveLocalRefs(swaggerJSON).resolved;
44
45 var fileName = options.filename || "api-doc";
46 var markdownOutputFile = this.data.dest + '/' + fileName + ".md";
47 var htmlOutputFile = this.data.dest + '/' + fileName + ".html";
48
49 // Parse the Swagger schema and reform to our liking
50 lodash.forIn(apiModel.paths, function (path) {
51
52 lodash.forIn(path, function (verb) {
53
54 lodash.forIn(verb.responses, function (response) {
55
56 response.schemaArr = [];
57
58 recurvsiveFlatten(undefined, response.schema, response.schemaArr, -1);
59
60 });
61 });
62 });
63
64 grunt.file.write(markdownOutputFile, nunjucks.render(__dirname + '/../templates/snippet.md', apiModel));
65 grunt.file.write(htmlOutputFile, nunjucks.render(__dirname + '/../templates/shell.html', apiModel));
66 grunt.log.writeln('Files created.');
67
68 });
69};
70
71
72// Swagger spec may lead to a high degree of nesting in response objects (objects within objects with objects, etc). This
73// function flattens that schmema and assigns each schema item a "depth" property. The outer object wrapper has depth -1.
74function recurvsiveFlatten(name, obj, arr, depth){
75
76 var type;
77
78 // "items" property flags a nested object or array, so it needs special treatment
79 if (obj.hasOwnProperty('items')) {
80
81 type = obj.items.type;
82
83 // Keep track of what type of array this is (if it is an array type)
84 if (obj.type === 'array') {
85 type = lodash.capitalize(type) + '[]';
86 }
87
88 // Add the object or array to the flattened property array
89 arr.push({name: name, type: type, depth: depth});
90
91 // Loop thru the item's properties and execute the recursive function
92 lodash.forIn(obj.items.properties, function (val, key) {
93 recurvsiveFlatten(key, val, arr, depth + 1);
94 });
95
96 } else if (obj.hasOwnProperty('properties')) {
97
98 // Add the object to the flattened property array
99 arr.push({name: name, type: 'Object', depth: depth});
100
101 // Execute the recursive function on all properties
102 lodash.forIn(obj.properties, function(val, key){
103 recurvsiveFlatten(key, val, arr, depth + 1);
104 });
105 } else {
106
107 // Add the property to the flattened property array
108 arr.push({name: name, type: obj.type, description: obj.description, depth: depth});
109 }
110
111}