parent
8676bb9560
commit
152d2f643a
@ -0,0 +1,43 @@ |
||||
'use strict' |
||||
import { Plugin } from '@remixproject/engine' |
||||
import { Build, buildSite } from './docgen/site'; |
||||
import { render } from './docgen/render'; |
||||
import { Config, defaults } from './docgen/config'; |
||||
import { loadTemplates } from './docgen/templates'; |
||||
import { SolcInput, SolcOutput } from 'solidity-ast/solc'; |
||||
|
||||
const profile = { |
||||
name: 'docgen', |
||||
desciption: 'solidity doc gen plugin for Remix', |
||||
methods: ['docgen'], |
||||
events: [''], |
||||
version: '0.0.1' |
||||
} |
||||
|
||||
|
||||
|
||||
export class DocGen extends Plugin { |
||||
|
||||
constructor() { |
||||
super(profile) |
||||
} |
||||
|
||||
onActivation(): void { |
||||
//this.docgen([{ output: example, input: inp }])
|
||||
this.on('solidity', 'compilationFinished', (file, source, languageVersion, data, input, version) => { |
||||
this.docgen([{ output: data, input: JSON.parse(input) }]) |
||||
}) |
||||
} |
||||
|
||||
async docgen(builds: Build[], userConfig?: Config): Promise<void> { |
||||
const config = { ...defaults, ...userConfig }; |
||||
const templates = await loadTemplates(config.theme, config.root, config.templates); |
||||
const site = buildSite(builds, config, templates.properties ?? {}); |
||||
const renderedSite = render(site, templates, config.collapseNewlines); |
||||
for (const { id, contents } of renderedSite) { |
||||
await this.call('fileManager', 'setFile', id, contents) |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
@ -1,2 +0,0 @@ |
||||
service_name: circleci |
||||
repo_token: $COVERALLS_REPO_TOKEN |
@ -1 +0,0 @@ |
||||
[{"/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/index.tsx":"1","/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/App.tsx":"2","/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/utils/utils.ts":"3","/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/routes.tsx":"4","/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/AppContext.tsx":"5","/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/hooks/useLocalStorage.tsx":"6","/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/utils/template.ts":"7","/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/views/index.ts":"8","/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/views/ErrorView.tsx":"9","/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/views/HomeView.tsx":"10","/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/utils/index.ts":"11","/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/utils/publisher.ts":"12"},{"size":235,"mtime":1621830872059,"results":"13","hashOfConfig":"14"},{"size":3284,"mtime":1621832627202,"results":"15","hashOfConfig":"14"},{"size":3501,"mtime":1621832476597,"results":"16","hashOfConfig":"14"},{"size":673,"mtime":1621830872059,"results":"17","hashOfConfig":"14"},{"size":711,"mtime":1621832627220,"results":"18","hashOfConfig":"14"},{"size":1255,"mtime":1621830872059,"results":"19","hashOfConfig":"14"},{"size":3850,"mtime":1621832488723,"results":"20","hashOfConfig":"14"},{"size":80,"mtime":1621830872062,"results":"21","hashOfConfig":"14"},{"size":729,"mtime":1621830872062,"results":"22","hashOfConfig":"14"},{"size":6248,"mtime":1621832627316,"results":"23","hashOfConfig":"14"},{"size":54,"mtime":1621830872059,"results":"24","hashOfConfig":"14"},{"size":395,"mtime":1621830872060,"results":"25","hashOfConfig":"14"},{"filePath":"26","messages":"27","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"iuk8ym",{"filePath":"28","messages":"29","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"30","messages":"31","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"32","messages":"33","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"34","messages":"35","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"36","messages":"37","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"38","messages":"39","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"40","messages":"41","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"42","messages":"43","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"44","messages":"45","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"46","messages":"47","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"48","messages":"49","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/index.tsx",[],"/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/App.tsx",[],"/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/utils/utils.ts",[],"/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/routes.tsx",[],"/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/AppContext.tsx",[],"/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/hooks/useLocalStorage.tsx",[],"/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/utils/template.ts",[],"/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/views/index.ts",[],"/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/views/ErrorView.tsx",[],"/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/views/HomeView.tsx",[],"/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/utils/index.ts",[],"/Users/edsonalcala/RemixRepos/remix-ethdoc-plugin/src/utils/publisher.ts",[]] |
@ -0,0 +1,34 @@ |
||||
{ |
||||
"extends": [ |
||||
"plugin:@nrwl/nx/react", |
||||
"../../.eslintrc.json" |
||||
], |
||||
"ignorePatterns": [ |
||||
"!**/*" |
||||
], |
||||
"overrides": [ |
||||
{ |
||||
"files": [ |
||||
"*.ts", |
||||
"*.tsx", |
||||
"*.js", |
||||
"*.jsx" |
||||
], |
||||
"rules": {} |
||||
}, |
||||
{ |
||||
"files": [ |
||||
"*.ts", |
||||
"*.tsx" |
||||
], |
||||
"rules": {} |
||||
}, |
||||
{ |
||||
"files": [ |
||||
"*.js", |
||||
"*.jsx" |
||||
], |
||||
"rules": {} |
||||
} |
||||
] |
||||
} |
@ -0,0 +1,13 @@ |
||||
{ |
||||
"semi": false, |
||||
"singleQuote": true, |
||||
"trailingComma": "all", |
||||
"printWidth": 120, |
||||
"tabWidth": 2, |
||||
"useTabs": false, |
||||
"arrowParens": "avoid", |
||||
"bracketSpacing": true, |
||||
"jsxBracketSameLine": false, |
||||
"jsxSingleQuote": false, |
||||
"endOfLine": "lf" |
||||
} |
Before Width: | Height: | Size: 118 KiB |
@ -1,29 +0,0 @@ |
||||
# Remix EthDoc Plugin |
||||
|
||||
The Remix EthDoc plugin allow you to generate HTML documents from solidity smart contracts. It also gives you the capability to publish the generated HTML documents to IPFS. |
||||
|
||||
## Activate |
||||
|
||||
EthDoc consists of 2 plugins: the EthDoc Viewer and the EthdDoc Generator. The EthDoc Generator will activate the EthDoc Viewer, so to use EthDoc, you only need to activate EthDoc Generator. |
||||
|
||||
The following image illustrates both sections of the plugin. |
||||
|
||||
![Screenshot](img/ethdoc.png) |
||||
|
||||
The EthDoc viewer appears in a tab in the main area of the Remix Editor and the EthDoc generator will appear in the side panel. |
||||
|
||||
## How to generate documentation |
||||
|
||||
To generate HTML documents, the first thing you need to do is to compile smart contracts. |
||||
|
||||
Once the contracts are compiled, go to the EthDoc Generator in the side panel and click the button to generate the docs. To see the generated docs, click the EthDoc Viewer tab in Remix's Editor. |
||||
|
||||
## How to publish |
||||
|
||||
In order to publish an HTML document, you need to first select a generated HTML document and then click the "Publish" button. |
||||
|
||||
Then, you should be redirected to the published version of the HTML document. |
||||
|
||||
## Issues |
||||
|
||||
If you have any issues, please feel free to create an issue in our [Github repository](https://github.com/Machinalabs/remix-ethdoc-plugin/issues). |
@ -1,4 +0,0 @@ |
||||
site_name: Remix Ethdoc |
||||
nav: |
||||
- Home: index.md |
||||
theme: readthedocs |
@ -0,0 +1,62 @@ |
||||
{ |
||||
"name": "etherscan", |
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json", |
||||
"sourceRoot": "apps/remixdocgen/src", |
||||
"projectType": "application", |
||||
"implicitDependencies": [ |
||||
"docgen" |
||||
], |
||||
"targets": { |
||||
"build": { |
||||
"executor": "@nrwl/webpack:webpack", |
||||
"outputs": ["{options.outputPath}"], |
||||
"defaultConfiguration": "development", |
||||
"options": { |
||||
"compiler": "babel", |
||||
"outputPath": "dist/apps/remixdocgen", |
||||
"index": "apps/etherscan/src/index.html", |
||||
"baseHref": "/", |
||||
"main": "apps/etherscan/src/main.tsx", |
||||
"polyfills": "apps/etherscan/src/polyfills.ts", |
||||
"tsConfig": "apps/etherscan/tsconfig.app.json", |
||||
"assets": [ |
||||
"apps/etherscan/src/favicon.ico", |
||||
"apps/etherscan/src/assets" |
||||
], |
||||
"styles": ["apps/etherscan/src/styles.css"], |
||||
"scripts": [], |
||||
"webpackConfig": "apps/etherscan/webpack.config.js" |
||||
}, |
||||
"configurations": { |
||||
"development": { |
||||
}, |
||||
"production": { |
||||
"fileReplacements": [ |
||||
{ |
||||
"replace": "apps/etherscan/src/environments/environment.ts", |
||||
"with": "apps/etherscan/src/environments/environment.prod.ts" |
||||
} |
||||
] |
||||
} |
||||
} |
||||
}, |
||||
"serve": { |
||||
"executor": "@nrwl/webpack:dev-server", |
||||
"defaultConfiguration": "development", |
||||
"options": { |
||||
"buildTarget": "etherscan:build", |
||||
"hmr": true |
||||
}, |
||||
"configurations": { |
||||
"development": { |
||||
"buildTarget": "etherscan:build:development", |
||||
"port": 6003 |
||||
}, |
||||
"production": { |
||||
"buildTarget": "etherscan:build:production" |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"tags": [] |
||||
} |
@ -1,76 +0,0 @@ |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="utf-8" /> |
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1" /> |
||||
<meta name="theme-color" content="#000000" /> |
||||
<meta |
||||
name="description" |
||||
content="Web site created using create-react-app" |
||||
/> |
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> |
||||
<!-- |
||||
manifest.json provides metadata used when your web app is installed on a |
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ |
||||
--> |
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> |
||||
<!-- |
||||
Notice the use of %PUBLIC_URL% in the tags above. |
||||
It will be replaced with the URL of the `public` folder during the build. |
||||
Only files inside the `public` folder can be referenced from the HTML. |
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will |
||||
work correctly both with client-side routing and a non-root public URL. |
||||
Learn how to configure a non-root public URL by running `npm run build`. |
||||
--> |
||||
<!-- Global site tag (gtag.js) - Google Analytics --> |
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-146337217-7"></script> |
||||
<script> |
||||
window.dataLayer = window.dataLayer || []; |
||||
function gtag(){dataLayer.push(arguments);} |
||||
gtag('js', new Date()); |
||||
|
||||
gtag('config', 'UA-146337217-7'); |
||||
</script> |
||||
|
||||
<style> |
||||
*, |
||||
*:after, |
||||
*:before { |
||||
-webkit-box-sizing: border-box; |
||||
-moz-box-sizing: border-box; |
||||
box-sizing: border-box; |
||||
} |
||||
|
||||
body, |
||||
html { |
||||
margin: 0; |
||||
padding: 0; |
||||
height: 100%; |
||||
} |
||||
|
||||
body { |
||||
padding: 0.5em; |
||||
} |
||||
|
||||
</style> |
||||
|
||||
<title>Remix Plugin</title> |
||||
|
||||
</head> |
||||
<body> |
||||
<noscript>You need to enable JavaScript to run this app.</noscript> |
||||
<div id="root"></div> |
||||
<!-- |
||||
This HTML file is a template. |
||||
If you open it directly in the browser, you will see an empty page. |
||||
|
||||
You can add webfonts, meta tags, or analytics to this file. |
||||
The build step will place the bundled scripts into the <body> tag. |
||||
|
||||
To begin the development, run `npm start` or `yarn start`. |
||||
To create a production bundle, use `npm run build` or `yarn build`. |
||||
--> |
||||
</body> |
||||
</html> |
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 9.4 KiB |
@ -1,25 +0,0 @@ |
||||
{ |
||||
"short_name": "React App", |
||||
"name": "Create React App Sample", |
||||
"icons": [ |
||||
{ |
||||
"src": "favicon.ico", |
||||
"sizes": "64x64 32x32 24x24 16x16", |
||||
"type": "image/x-icon" |
||||
}, |
||||
{ |
||||
"src": "logo192.png", |
||||
"type": "image/png", |
||||
"sizes": "192x192" |
||||
}, |
||||
{ |
||||
"src": "logo512.png", |
||||
"type": "image/png", |
||||
"sizes": "512x512" |
||||
} |
||||
], |
||||
"start_url": ".", |
||||
"display": "standalone", |
||||
"theme_color": "#000000", |
||||
"background_color": "#ffffff" |
||||
} |
@ -1,3 +0,0 @@ |
||||
# https://www.robotstxt.org/robotstxt.html |
||||
User-agent: * |
||||
Disallow: |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
@ -0,0 +1,14 @@ |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="utf-8" /> |
||||
<title>Remix Docgen</title> |
||||
<base href="/" /> |
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" /> |
||||
<link rel="icon" type="image/x-icon" href="favicon.ico" /> |
||||
</head> |
||||
<body> |
||||
<div id="root"></div> |
||||
</body> |
||||
</html> |
@ -1,30 +0,0 @@ |
||||
import { CompiledContract, ABIParameter } from "@remixproject/plugin-api/lib/compiler"; |
||||
|
||||
import sampleData from "./sample-data/sample-artifact.json"; |
||||
import sampleDataWithComments from "./sample-data/sample-artifact-with-comments.json"; |
||||
|
||||
export const buildFakeArtifact: () => CompiledContract = () => { |
||||
const result = (sampleData as never) as CompiledContract; |
||||
return result; |
||||
}; |
||||
|
||||
export const buildFakeArtifactWithComments: () => CompiledContract = () => { |
||||
const result = (sampleDataWithComments as never) as CompiledContract; |
||||
return result; |
||||
}; |
||||
|
||||
export const buildFakeABIParameter: () => ABIParameter = () => { |
||||
return { |
||||
internalType: "address", |
||||
name: "allocator", |
||||
type: "address", |
||||
}; |
||||
}; |
||||
|
||||
export const buildFakeABIParameterWithDocumentation: () => ABIParameter = () => { |
||||
return { |
||||
internalType: "address", |
||||
name: "allocator", |
||||
type: "address", |
||||
}; |
||||
}; |
@ -1,2 +0,0 @@ |
||||
export * from "./utils"; |
||||
export * from "./publisher"; |
@ -1,40 +0,0 @@ |
||||
import { publish } from "./publisher"; |
||||
|
||||
// tslint:disable-next-line
|
||||
const open = require("open"); |
||||
|
||||
jest.setTimeout(10000); |
||||
|
||||
describe("Publisher tests", () => { |
||||
test("it can publish", async () => { |
||||
const result = await publish("hello 123"); |
||||
|
||||
expect(result).toBeDefined(); |
||||
}); |
||||
|
||||
test("it can publish html", async () => { |
||||
const result = await publish(` |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="utf-8" /> |
||||
<meta |
||||
name="description" |
||||
content="Web site created using create-react-app" |
||||
/> |
||||
</head> |
||||
<body> |
||||
<div>Content custom</div> |
||||
</body> |
||||
</html> |
||||
`);
|
||||
|
||||
// Uncomment for testing
|
||||
|
||||
// const url = `https://ipfs.io/ipfs/${result}`;
|
||||
|
||||
// await open(url, { app: ['google chrome', '--incognito'] });
|
||||
|
||||
expect(result).toBeDefined(); |
||||
}); |
||||
}); |
@ -1,18 +0,0 @@ |
||||
import { HTMLContent } from "./types"; |
||||
|
||||
// tslint:disable-next-line
|
||||
const IpfsClient = require("ipfs-mini"); |
||||
|
||||
export const publish = async (content: HTMLContent) => { |
||||
const ipfs = new IpfsClient({ |
||||
host: "ipfs.infura.io", |
||||
port: 5001, |
||||
protocol: "https", |
||||
}); |
||||
|
||||
const documentHash = await ipfs.add(content); |
||||
|
||||
console.log("Document hash", documentHash); |
||||
|
||||
return documentHash; |
||||
}; |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,151 +0,0 @@ |
||||
import { |
||||
FunctionDocumentation, |
||||
TemplateDoc, |
||||
MethodDoc, |
||||
ContractDocumentation, |
||||
ParameterDocumentation, |
||||
} from "./types"; |
||||
type HTMLContent = string; |
||||
|
||||
export const htmlTemplate = (content: HTMLContent) => { |
||||
return ` |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="utf-8" /> |
||||
<meta |
||||
name="description" |
||||
content="Web site created with EthDoc" |
||||
/> |
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> |
||||
</head> |
||||
<body> |
||||
${content} |
||||
</body> |
||||
</html> |
||||
`;
|
||||
}; |
||||
|
||||
export const template = ( |
||||
name: string, |
||||
contractDoc: ContractDocumentation, |
||||
functions: FunctionDocumentation[] |
||||
) => ` |
||||
<style> |
||||
#ethdoc-viewer{ |
||||
font-size: 0.8em; |
||||
padding: 1em; |
||||
} |
||||
#ethdoc-viewer .lead{ |
||||
font-size: 1em; |
||||
} |
||||
#ethdoc-viewer table { |
||||
width: 50%; |
||||
} |
||||
#ethdoc-viewer hr { |
||||
margin: 0; |
||||
margin-bottom: 0.5rem; |
||||
} |
||||
#ethdoc-viewer p{ |
||||
margin-bottom: 0.5rem; |
||||
} |
||||
</style> |
||||
|
||||
<div id="ethdoc-viewer"> |
||||
|
||||
${functions.length === 0 |
||||
? "No contract to display" |
||||
: renderHeader(name, contractDoc) |
||||
} |
||||
|
||||
${functions |
||||
.map( |
||||
(item) => ` |
||||
<hr> |
||||
<h6>${item.name}</h6> |
||||
|
||||
${getMethodDetails(item.devdoc)} |
||||
|
||||
${renderParameterDocumentation(item.inputs)} |
||||
|
||||
<p>Returns:</p> |
||||
|
||||
${renderParameterDocumentation(item.outputs)} |
||||
` |
||||
) |
||||
.join("\n")} |
||||
|
||||
</div> |
||||
`;
|
||||
|
||||
const devMethodDocTemplate: Partial<TemplateDoc<MethodDoc>> = { |
||||
author: (author: string) => `<p>Created By ${author}</p>`, |
||||
details: (details: string) => `<p>${details}</p>`, |
||||
return: (value: string) => `<p>Return : ${value}</p>`, |
||||
notice: (notice: string) => (notice ? `<p>${notice}</p>` : ""), |
||||
// returns: () => '', // Implemented by getParams()
|
||||
params: () => "", // Implemented by getParams()
|
||||
}; |
||||
|
||||
export const renderHeader = ( |
||||
name: string, |
||||
contractDoc: ContractDocumentation |
||||
) => ` |
||||
<h3>${name} ${contractDoc.title ? `<small>: ${contractDoc.title}</small>` : "" |
||||
}</h3> |
||||
|
||||
${contractDoc.notice ? `<p class="lead">${contractDoc.notice}</p>` : ""} |
||||
|
||||
${contractDoc.author ? `<p>Author: ${contractDoc.author}</p>` : ""} |
||||
|
||||
<br /> |
||||
<p><strong>Functions</strong></p> |
||||
`;
|
||||
|
||||
export const renderParameterDocumentation = ( |
||||
parameters: ParameterDocumentation[] |
||||
) => |
||||
`${parameters.length > 0 |
||||
? `<table class="table table-sm table-bordered table-striped">
|
||||
<thead> |
||||
<tr> |
||||
<th>Name</th> |
||||
<th>Type</th> |
||||
<th>Description</th> |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
${parameters |
||||
.map( |
||||
(output) => `<tr>
|
||||
<td>${output.name}</td> |
||||
<td>${output.type}</td> |
||||
<td>${output.description}</td> |
||||
</tr>` |
||||
) |
||||
.join("")} |
||||
</tbody> |
||||
</table>` |
||||
: "<p>No parameters</p>" |
||||
}`;
|
||||
|
||||
export const getMethodDetails = (devMethod?: Partial<MethodDoc>) => { |
||||
const finalResult = !devMethod |
||||
? "<p><strong>**Add Documentation for the method here**</strong></p>" |
||||
: Object.keys(devMethod) |
||||
.filter((key) => key !== "params") |
||||
.map((key) => { |
||||
const funcToGetTemplate = (devMethodDocTemplate as any)[key]; |
||||
|
||||
if (!funcToGetTemplate) { |
||||
return ""; |
||||
} |
||||
const funcParameter = (devMethod as any)[key]; |
||||
const result = funcToGetTemplate(funcParameter); |
||||
return result; |
||||
}) |
||||
.join("\n"); |
||||
|
||||
console.log("finalResult", finalResult); |
||||
return finalResult; |
||||
}; |
@ -1,41 +0,0 @@ |
||||
import { |
||||
UserMethodDoc, |
||||
DevMethodDoc, |
||||
DeveloperDocumentation, |
||||
UserDocumentation, |
||||
} from "@remixproject/plugin-api/lib/compiler"; |
||||
|
||||
export interface MethodsDocumentation { |
||||
[x: string]: UserMethodDoc | DevMethodDoc; |
||||
} |
||||
|
||||
export interface ContractDocumentation { |
||||
methods: MethodsDocumentation; |
||||
author: string; |
||||
title: string; |
||||
details: string; |
||||
notice: string; |
||||
} |
||||
|
||||
export type MethodDoc = DevMethodDoc & UserMethodDoc; |
||||
|
||||
export type TemplateDoc<T> = { [key in keyof T]: (...params: any[]) => string }; |
||||
|
||||
// Contract
|
||||
export type ContractDoc = DeveloperDocumentation & UserDocumentation; |
||||
|
||||
export interface FunctionDocumentation { |
||||
name: string; |
||||
type: string; |
||||
devdoc?: Partial<MethodDoc>; |
||||
inputs: ParameterDocumentation[]; |
||||
outputs: ParameterDocumentation[]; |
||||
} |
||||
|
||||
export interface ParameterDocumentation { |
||||
name: string; |
||||
type: string; |
||||
description: string; |
||||
} |
||||
|
||||
export type HTMLContent = string; |
File diff suppressed because one or more lines are too long
@ -1,125 +0,0 @@ |
||||
import { |
||||
CompilationResult, |
||||
CompiledContract, |
||||
FunctionDescription, |
||||
ABIParameter, |
||||
ABIDescription, |
||||
} from "@remixproject/plugin-api/lib/compiler"; |
||||
|
||||
import { FileName, Documentation, ContractName } from "../types"; |
||||
import { template } from "./template"; |
||||
import { |
||||
ContractDocumentation, |
||||
MethodDoc, |
||||
FunctionDocumentation, |
||||
ParameterDocumentation, |
||||
} from "./types"; |
||||
|
||||
export const createDocumentation = ( |
||||
fileName: FileName, |
||||
compilationResult: CompilationResult |
||||
) => { |
||||
console.log("Filename", fileName); |
||||
const result = new Map<ContractName, Documentation>(); |
||||
|
||||
const contracts = compilationResult.contracts[fileName]; |
||||
console.log("Contracts", contracts); |
||||
|
||||
Object.keys(contracts).forEach((name) => { |
||||
console.log("CompiledContract", JSON.stringify(contracts[name])); |
||||
result.set(name, getContractDoc(name, contracts[name])); |
||||
}); |
||||
|
||||
return result; |
||||
}; |
||||
|
||||
export const getContractDoc = (name: string, contract: CompiledContract) => { |
||||
const contractDoc: ContractDocumentation = getContractDocumentation(contract); |
||||
|
||||
const onlyFunctions = contract.abi.filter((item) => { |
||||
return item.type !== "event"; |
||||
}); |
||||
|
||||
const functionsDocumentation = onlyFunctions.map((def: ABIDescription) => { |
||||
if (def.type === "constructor") { |
||||
def.name = "constructor"; |
||||
// because "constructor" is a string and not a { notice } object for userdoc we need to do that
|
||||
const methodDoc = { |
||||
...(contract.devdoc.methods.constructor || {}), |
||||
notice: |
||||
Object.keys(contract.userdoc.methods.constructor).length > 0 |
||||
? (contract.userdoc.methods.constructor as string) |
||||
: "", |
||||
}; |
||||
return getFunctionDocumentation(def, methodDoc); |
||||
} else { |
||||
if (def.type === "fallback") { |
||||
def.name = "fallback"; |
||||
} |
||||
const method = Object.keys(contractDoc.methods).find((key) => |
||||
key.includes(def.name as string) |
||||
) as string; |
||||
const methodDoc = contractDoc.methods[method]; |
||||
return getFunctionDocumentation(def as FunctionDescription, methodDoc); |
||||
} |
||||
}); |
||||
|
||||
// console.log("contractDoc", contractDoc)
|
||||
// console.log("functionsDocumentation", functionsDocumentation)
|
||||
|
||||
try { |
||||
const finalResult = template(name, contractDoc, functionsDocumentation); |
||||
return finalResult |
||||
|
||||
} catch (error) { |
||||
console.log("ERROR", error) |
||||
return '' |
||||
} |
||||
|
||||
}; |
||||
|
||||
export const getContractDocumentation = (contract: CompiledContract) => { |
||||
const methods = { ...contract.userdoc.methods, ...contract.devdoc.methods } |
||||
const contractDoc = { ...contract.userdoc, ...contract.devdoc, ...methods }; |
||||
|
||||
return contractDoc; |
||||
}; |
||||
|
||||
export const getFunctionDocumentation = ( |
||||
def: FunctionDescription, |
||||
devdoc?: Partial<MethodDoc> |
||||
) => { |
||||
const doc = devdoc || {}; |
||||
const devparams = doc.params || {}; |
||||
const inputsWithDescription = mergeParametersWithDevdoc( |
||||
def.inputs || [], |
||||
devparams |
||||
); |
||||
const outputsWithDescription = mergeParametersWithDevdoc( |
||||
def.outputs || [], |
||||
devparams |
||||
); |
||||
const type = def.constant ? "view" : "read"; |
||||
|
||||
return { |
||||
name: def.name, |
||||
type, |
||||
devdoc, |
||||
inputs: inputsWithDescription, |
||||
outputs: outputsWithDescription, |
||||
} as FunctionDocumentation; |
||||
}; |
||||
|
||||
export const mergeParametersWithDevdoc = ( |
||||
params: ABIParameter[], |
||||
devparams: any |
||||
) => { |
||||
return params.map((input) => { |
||||
const description = devparams[input.name] || ""; |
||||
return { |
||||
name: input.name, |
||||
type: input.type, |
||||
description, |
||||
} as ParameterDocumentation; |
||||
}); |
||||
}; |
@ -1,16 +0,0 @@ |
||||
{ |
||||
"extends": [ |
||||
"tslint:recommended", |
||||
"tslint-react", |
||||
"tslint-config-prettier" |
||||
], |
||||
"rulesDirectory": [ |
||||
"tslint-plugin-prettier" |
||||
], |
||||
"rules": { |
||||
"prettier": true, |
||||
"interface-name": false, |
||||
"no-console": false, |
||||
"jsx-no-lambda": false |
||||
} |
||||
} |
Loading…
Reference in new issue