Skip to content

Commit

Permalink
Feature styled apidocs (hyperledger-archives#2267)
Browse files Browse the repository at this point in the history
* produced markdown api docs

* turn off jsdoc

* updates for unittests

* put back what git took away

* cleanup stray comment

* link checker

* remove api link;
  • Loading branch information
mbwhite authored Oct 2, 2017
1 parent d475466 commit 67c5092
Show file tree
Hide file tree
Showing 19 changed files with 406 additions and 81 deletions.
1 change: 0 additions & 1 deletion packages/composer-client/lib/businessnetworkconnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ const LOG = Logger.getLog('BusinessNetworkConnection');
* Use this class to connect to and then interact with a deployed BusinessNetworkDefinition.
* Use the AdminConnection class in the composer-admin module to deploy BusinessNetworksDefinitions.
* @extends EventEmitter
* @see See [EventEmitter]{@link module:composer-client.EventEmitter}
* @class
* @memberof module:composer-client
*/
Expand Down
98 changes: 98 additions & 0 deletions packages/composer-common/lib/codegen/fromjs/jsongenerator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

const fs = require('fs');
const path = require('path');
// const Writer = require('../writer');

/**
* @private
* @class
* @memberof module:composer-common
*/
class JSONGenerator {

/**
* @param {Object} program - the program arguments
* @param {Object} file - the file instance being processed
* @param {Object[]} includes - the includes (require statements) within the file
* @param {Object[]} classes - the classes within the file
* @param {Object[]} functions - the functions within the file
*/
generate(program, file, includes, classes, functions) {
let data = classes[0];
if (data){
data.description = data.commentData.description.split('\n');
data.seeAlso=[];
data.visibility='public';
data.commentData.tags.forEach((e)=>{
if (e.title==='extends'){
data.extends=e.name;
} else if (e.title === 'see'){
// "See [Registry]{@link module:composer-client.Registry}"
let s1 = e.description.substring(0,e.description.indexOf('{'));
let a = e.description.indexOf('}');
let b = e.description.lastIndexOf('.')+1;
data.seeAlso.push(s1+'('+e.description.substring(a,b).toLowerCase()+')');
} else if (e.title === 'memberof'){

data.module=e.description.substr(e.description.indexOf('-')+1);

} else if (e.title === 'private'){
data.visibility ='private';
} else if (e.title === 'protected'){
data.visibility='protected';
}
});
delete data.tags;



let listMethods = data.methods;
listMethods
.forEach((e)=>{
e.description = e.commentData.description.split('\n');
e.parameters = [];
e.commentData.tags.forEach( (p)=>{
if (p.title==='param'){
let oneParam = {};
oneParam.description=p.description;
if (p.type.type==='OptionalType'){
oneParam.type=p.type.expression.name;
oneParam.name=p.name;
oneParam.optional=true;
} else {
oneParam.type=p.type.name;
oneParam.name=p.name;
oneParam.optional=true;
}
e.parameters.push(oneParam);
} else if (p.title.startsWith('return')) {
e.return={description:p.description.split('\n'),
type : p.type.name};
}
});
});

let f = path.resolve(program.outputDir, path.parse(file).name+'.json');
fs.writeFileSync(f,JSON.stringify(data));
}
// console.log(JSON.stringify(data));
}
}


module.exports = JSONGenerator;
14 changes: 10 additions & 4 deletions packages/composer-common/lib/codegen/javascriptparser.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,16 @@ class JavaScriptParser {
} else if (statement.type === 'ClassDeclaration') {
let closestComment = JavaScriptParser.findCommentBefore(statement.start, statement.end, previousEnd, comments);
let privateClass = false;
let d;
if(closestComment >= 0) {
let comment = comments[closestComment].value;
d = doctrine.parse(comment, {unwrap: true, sloppy: true});
privateClass = JavaScriptParser.getVisibility(comment) === '-';
}

if(privateClass === false || includePrivates) {
const clazz = { name: statement.id.name};
d = d || [];
const clazz = { name: statement.id.name , commentData : d };
clazz.methods = [];

for(let n=0; n < statement.body.body.length; n++) {
Expand All @@ -175,16 +178,18 @@ class JavaScriptParser {
let throws = '';
let decorators = [];
let example = '';
let commentData;
if(closestComment >= 0) {
let comment = comments[closestComment].value;
commentData = doctrine.parse(comment, {unwrap: true, sloppy: true});
returnType = JavaScriptParser.getReturnType(comment);
visibility = JavaScriptParser.getVisibility(comment);
methodArgs = JavaScriptParser.getMethodArguments(comment);
decorators = JavaScriptParser.getDecorators(comment);
throws = JavaScriptParser.getThrows(comment);
example = JavaScriptParser.getExample(comment);
}

commentData = commentData || [];
if(visibility === '+' || includePrivates) {
const method = {
visibility: visibility,
Expand All @@ -193,7 +198,8 @@ class JavaScriptParser {
methodArgs: methodArgs,
decorators: decorators,
throws: throws,
example: example
example: example,
commentData : commentData
};
clazz.methods.push(method);
}
Expand Down Expand Up @@ -468,4 +474,4 @@ class JavaScriptParser {
}
}

module.exports = JavaScriptParser;
module.exports = JavaScriptParser;
5 changes: 4 additions & 1 deletion packages/composer-common/lib/codegen/parsejs.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const program = require('commander');
const PlantUMLGenerator = require('./fromjs/plantumlgenerator');
const APISignatureGenerator = require('./fromjs/apisignaturegenerator');
const JavaScriptParser = require('./javascriptparser');

const JSONGenerator = require('./fromjs/jsongenerator');
/**
* Generates Plant UML files from Javascript source files
*
Expand All @@ -47,6 +47,9 @@ case 'PlantUML':
case 'APISignature':
fileProcessor = new APISignatureGenerator();
break;
case 'JSON':
fileProcessor = new JSONGenerator();
break;
}

console.log('Input dir ' + program.inputDir);
Expand Down
2 changes: 1 addition & 1 deletion packages/composer-common/test/codegen/javascriptparser.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ describe('JavascriptParser', () => {
`;

const parser = new JavascriptParser(contents);
parser.getClasses().should.deep.equal([{ name: 'cls', methods: [] }]);
parser.getClasses().should.deep.equal([{ name: 'cls', methods: [],commentData:[] }]);
});
});

Expand Down
8 changes: 7 additions & 1 deletion packages/composer-website/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,10 @@ out

# Ignore temporary built installers.
installers/*/install.sh
jekylldocs/install*.sh
<<<<<<< 4b6e003898216b4b101ca9793443d0072efd85a6
jekylldocs/install*.sh
=======
jekylldocs/install*.sh
jsondata/**
jekylldocs/api-doc-inline/**/*
>>>>>>> updates for unittests
70 changes: 70 additions & 0 deletions packages/composer-website/apigen-opus/_template/class.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
layout: default
title: {{name}} ({{module | capitalize }} API)
section: api
sidebar: sidebars/accordion-toc0.md
excerpt: The Client, Admin, and Runtime components of Hyperledger Composer .
index-order: {{index}}
---
# {{name}}

{{commentData.description}}

### Details
- **Extends** {{extends}}
- **Module** {{module}}

### See also
{% for sa in seeAlso -%}
- {{sa}}
{% endfor %}

## Method Summary
| Returns | Name | Description |
| :-------- | :---- | :----------- |
{% for method in methods | sort(attribute='name') %}| `{{method.returnType}}` | [{{method.name}}](#{{method.name | lower }}{% for args in method.methodArgs %}-{{args | lower }}{% endfor %}) | {{method.description[0]}} |
{% endfor %}

## Method Details
{% for method in methods %}
{% if method.name == 'constructor'%}
## new {{name}}()
{% else %}
## {{method.name}}({% for args in method.methodArgs %}{{args | lower }}{% if not loop.last %},{% endif %}{% endfor %})
{% endif %}



{% for l in method.description -%}
{{l}}
{% endfor %}

{% if method.example %}
### Example
```javascript
{{method.example}}
```
{% endif %}

{% if method.return %}

### Returns
`{{method.return.type}}` - {% for l in method.return.description -%}
{{l}}
{% endfor %}

{% endif %}


### Parameters
{% if method.parameters | length != 0 -%}
| Name | Type | Optional | Description |
| :----------- | :----------- | :----------- | :----------- |
{% for p in method.parameters -%}
|**{{p.name}}**|`{{p.type}}`|{{p.optional}}|{{p.description}}|
{% endfor %}
{% else %}

No parameters
{% endif %}
{% endfor %}
42 changes: 42 additions & 0 deletions packages/composer-website/apigen-opus/bin/cli1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env node

const classopus = require('../lib/classopus');
const yargs = require('yargs');

// Standard Command yargs processing.
let results = yargs
.option('i', {
alias: 'input',
demandOption: false,
describe: 'Input JSON',
type: 'string'
})
.option('o', {
alias: 'outdir',
demandOption: false,
default: './out',
describe: 'Output Directory',
type: 'string'
}).option('t', {
alias: 'template',
demandOption: false,
default: 'default.njk',
describe: 'Template file to use as basis for markdown',
type: 'string'
}).option('n', {
alias: 'indexname',
demandOption: false,
default: 'bnd-opus.md',
describe: 'Name of the generated markdown file',
type: 'string'
}).option('c',{
alias: 'context',
default : '{}',
describe: 'Additional options to pass to the template engine\'s context',
type: 'string'
})
.strict()
.help().argv;

classopus(results);

52 changes: 52 additions & 0 deletions packages/composer-website/apigen-opus/lib/classopus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

const path = require("path");
const fs = require("fs");
const nunjucks = require("nunjucks");
const util = require("util");
const mkdirp = require("mkdirp");

// convience method
let LOG = console.log;

// main function
function go(args) {

mkdirp(args.outdir);

// sort out template and target file
const targetFile = path.resolve(args.outdir, path.parse(args.input).name + '.md');
const contextFile = path.resolve(args.input + '.json');
const templatePath = path.resolve(__dirname, "..", "_template");

// Note autoescape false - otherwise the --> in the cto file is replaced with --&gt;
let env = nunjucks.configure(templatePath, { autoescape: false });


let context = JSON.parse(args.context);

Promise.resolve()
// parse that
.then((result) => {

}).then(() => {
let str = fs.readFileSync(contextFile);
Object.assign(context,JSON.parse(str));

// render the model
let renderedMarkown = env.render(args.template, context);

// and write out the file
fs.writeFileSync(targetFile, renderedMarkown, { encoding: "utf8" });
console.log("All written to " + targetFile);
})
.catch(error => {
console.log(error);
});


}




module.exports = go;
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
<div class="footer-right-break">
<ul>
<li><a href="https://github.com/hyperledger/composer">GitHub</a></li>
<!-- <li><a href="https://github.com/hyperledger/composer/LICENSE.txt">Legal</a></li> -->
<li><a href="{{site.baseurl}}/jsdoc/index.html">APIs</a></li>
<li><a href="http://stackoverflow.com/questions/tagged/fabric-composer">Stack Overflow</a></li>
<li><a href="https://goo.gl/forms/7YPMLP2LTN2hjIRk2">Feedback?</a></li>
</ul>
Expand Down
7 changes: 7 additions & 0 deletions packages/composer-website/jekylldocs/_includes/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,16 @@ <h1 ><a href="{{site.baseurl}}/index.html" class="logot">Hyperledger Composer</a
<a href="{{site.baseurl}}/reference/index.html">Reference</a>
{{ reference | markdownify }}
</li>
<li>
<a href="{{site.baseurl}}/api-doc/index.html">API</a>
{{ api | markdownify }}
</li>
<li>
<a href="{{site.baseurl}}/support/index.html">Support</a>
</li>

<li>

</ul>
</nav>
</div><!-- /.container -->
Expand Down
Loading

0 comments on commit 67c5092

Please sign in to comment.