-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
157 lines (117 loc) · 4.24 KB
/
index.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
const aglio = require('aglio');
const watch = require('node-watch');
const path = require('path');
const fs = require('fs');
const _options = {
source: '',//input path/file eg /docs/source/index.apib OR /docs/source
output: '',//output path/file eg /docs/html/index.html OR /docs/html
watch: true,
expose: true,
uri: '/docs',
debug: true,
log: function(){
this.debug && console.log.apply(console,arguments);
},
aglioOptions:{}, //options to pass specifically to aglio
};
function validateOptions(options){
var sourceStat = fs.statSync(options.source);
if(!sourceStat.isDirectory() && !sourceStat.isFile()){
throw new Error('express-aglio: options.source is not a file or directory. check path and try again.');
}
var outputStat = fs.statSync(options.output);
if(!outputStat.isDirectory() && !outputStat.isFile()){
throw new Error('express-aglio: options.output is not a file or directory. check path and try again.');
}
['watch','debug','expose'].forEach(function(prop){
if(typeof options[prop] !== 'boolean'){
throw new Error( 'express-aglio: options.%s must be a boolean value (true/false).'.replace('%s',prop) );
}
});
if(typeof options.log !== 'function'){
throw new Error('express-aglio: options.log must be a function. to disable built in logger use options.debug = false.');
}
};
function generateFileList(options,callback){
var sourceIsDir = fs.lstatSync(options.source).isDirectory();
var outputIsDir = fs.lstatSync(options.output).isDirectory();
options.serveDir = options.output;
if(!outputIsDir){
options.serveDir = options.serveDir.split('/');
options.serveDir.pop();
options.serveDir = options.serveDir.join('/') +'/';
}
if(sourceIsDir && outputIsDir){
fs.readdir(options.source,function(err,files){
if(err)
options.log('express-aglio: error reading source directory.');
else
var fileList = [];
files.forEach(function(file){
if(file.slice((file.lastIndexOf(".") - 1 >>> 0) + 2) == 'apib'){
fileList.push({
source: file,
output: file.replace('.apib','.html')
});
}
});
callback(fileList);
});
}
else if(!sourceIsDir && !outputIsDir){
var fileList = [{
source: options.source,
output: options.output,
}];
callback(fileList);
}else{
throw new Error('express-aglio: output and source must both be either directories or single files.');
}
};
module.exports = function( app, __options ) {
//first step: parse and validate options.
const options = {..._options,...__options};
validateOptions(options);
const outputIsDir = fs.lstatSync(options.output).isDirectory();
options.serveDir = options.output;
if(!outputIsDir){
options.serveDir = options.serveDir.split('/');
options.serveDir.pop();
options.serveDir = options.serveDir.join('/') +'/';
}
//mount doc route immediately
if(options.expose){
const express = require('express');
options.log('express-aglio: started with options:',options);
app.use(options.uri,express.static(options.serveDir));
}
//second step: generate the file list
generateFileList(options,fileList=>{
const buildFn = () => {
return Promise.all(fileList.map(fStruct=>{
return new Promise((resolve,reject)=>{
aglio.renderFile( fStruct.source, fStruct.output,options.aglioOptions,function (err, warnings) {
if(err){
options.log('express-aglio: error building doc from source file `%s`'+"\r\n",fStruct.source);
options.log('express-aglio: aglio error details '+"\r\n");
options.log(err);
reject(err);
}else{
resolve();
}
});
});
}));
}
//third step: generate the build step
buildFn().then(()=>{
options.log('express-aglio: built docs(startup)');
//sixth and final step: setup watch and routes
if(options.watch){
//build docs on every change.
watch(path.dirname(options.source),buildFn);
options.log('express-aglio: watching filesystem for changes');
}
});
});
};