Comparing version 1.1.29 to 2.0.0-beta.1
@@ -1,4 +0,10 @@ | ||
export * from './converter'; | ||
export * from './etherscanParser'; | ||
export * from './fileParser'; | ||
export * from './converterAST2Classes'; | ||
export * from './converterClass2Dot'; | ||
export * from './converterClasses2Dot'; | ||
export * from './converterClasses2Storage'; | ||
export * from './parserEtherscan'; | ||
export * from './parserFiles'; | ||
export * from './parserGeneral'; | ||
export * from './typeGuards'; | ||
export * from './umlClass'; | ||
export * from './writerFiles'; |
@@ -13,6 +13,12 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__exportStar(require("./converter"), exports); | ||
__exportStar(require("./etherscanParser"), exports); | ||
__exportStar(require("./fileParser"), exports); | ||
__exportStar(require("./converterAST2Classes"), exports); | ||
__exportStar(require("./converterClass2Dot"), exports); | ||
__exportStar(require("./converterClasses2Dot"), exports); | ||
__exportStar(require("./converterClasses2Storage"), exports); | ||
__exportStar(require("./parserEtherscan"), exports); | ||
__exportStar(require("./parserFiles"), exports); | ||
__exportStar(require("./parserGeneral"), exports); | ||
__exportStar(require("./typeGuards"), exports); | ||
__exportStar(require("./umlClass"), exports); | ||
__exportStar(require("./writerFiles"), exports); | ||
//# sourceMappingURL=index.js.map |
#! /usr/bin/env node | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const etherscanParser_1 = require("./etherscanParser"); | ||
const fileParser_1 = require("./fileParser"); | ||
const contractFilter_1 = require("./contractFilter"); | ||
const converterClasses2Dot_1 = require("./converterClasses2Dot"); | ||
const parserGeneral_1 = require("./parserGeneral"); | ||
const parserEtherscan_1 = require("./parserEtherscan"); | ||
const filterClasses_1 = require("./filterClasses"); | ||
const commander_1 = require("commander"); | ||
const converterClasses2Storage_1 = require("./converterClasses2Storage"); | ||
const converterStorage2Dot_1 = require("./converterStorage2Dot"); | ||
const regEx_1 = require("./utils/regEx"); | ||
const writerFiles_1 = require("./writerFiles"); | ||
const program = new commander_1.Command(); | ||
const debugControl = require('debug'); | ||
const debug = require('debug')('sol2uml'); | ||
const commander_1 = require("commander"); | ||
const program = new commander_1.Command(); | ||
program | ||
.usage(`[subcommand] <options> | ||
The three subcommands: | ||
* class: Generates a UML class diagram from Solidity source code. default | ||
* storage: Generates a diagram of a contract's storage slots. | ||
* flatten: Pulls verified source files from a Blockchain explorer into one, flat, local Solidity file. | ||
The Solidity code can be pulled from verified source code on Blockchain explorers like Etherscan or from local Solidity files.`) | ||
.addOption(new commander_1.Option('-sf, --subfolders <value>', 'number of subfolders that will be recursively searched for Solidity files.').default('-1', 'all')) | ||
.addOption(new commander_1.Option('-f, --outputFormat <value>', 'output file format.') | ||
.choices(['svg', 'png', 'dot', 'all']) | ||
.default('svg')) | ||
.option('-o, --outputFileName <value>', 'output file name') | ||
.option('-i, --ignoreFilesOrFolders <filesOrFolders>', 'comma separated list of files or folders to ignore') | ||
.addOption(new commander_1.Option('-n, --network <network>', 'Ethereum network') | ||
.choices([ | ||
'mainnet', | ||
'polygon', | ||
'bsc', | ||
'arbitrum', | ||
'ropsten', | ||
'kovan', | ||
'rinkeby', | ||
'goerli', | ||
]) | ||
.default('mainnet')) | ||
.option('-k, --apiKey <key>', 'Etherscan, Polygonscan, BscScan or Arbiscan API key') | ||
.option('-v, --verbose', 'run with debugging statements', false); | ||
program | ||
.command('class', { isDefault: true }) | ||
.description('Generates a UML class diagram from Solidity source code.') | ||
.usage(`<fileFolderAddress> [options] | ||
@@ -23,82 +58,86 @@ | ||
sol2uml 0x79fEbF6B9F76853EDBcBc913e6aAE8232cFB9De9`) | ||
.argument('[fileFolderAddress]', 'file name, base folder or contract address', process.cwd()) | ||
.option('-b, --baseContractNames <value>', 'only output contracts connected to these comma separated base contract names') | ||
.option('-f, --outputFormat <value>', 'output file format: svg, png, sol, dot or all', 'svg') | ||
.option('-o, --outputFileName <value>', 'output file name') | ||
.option('-d, --depthLimit <depth>', 'number of sub folders that will be recursively searched for Solidity files. Default -1 is unlimited', '-1') | ||
.option('-i, --ignoreFilesOrFolders <filesOrFolders>', 'comma separated list of files or folders to ignore') | ||
.option('-n, --network <network>', 'mainnet, polygon, bsc, ropsten, kovan, rinkeby or goerli', 'mainnet') | ||
.option('-a, --hideAttributes', 'hide class and interface attributes') | ||
.option('-p, --hideOperators', 'hide class and interface operators/functions') | ||
.option('-e, --hideEnums', 'hide enum types') | ||
.option('-s, --hideStructs ', 'hide data structures') | ||
.option('-l, --hideLibraries ', 'hide libraries') | ||
.option('-t, --hideInterfaces ', 'hide interfaces') | ||
.option('-r, --hideInternals', 'hide private and internal attributes and operators') | ||
.option('-k, --etherscanApiKey <key>', 'Etherscan API Key') | ||
.option('-c, --clusterFolders', 'cluster contracts into source folders') | ||
.option('-v, --verbose', 'run with debugging statements') | ||
.parse(process.argv); | ||
const options = program.opts(); | ||
if (options.verbose) { | ||
debugControl.enable('sol2uml'); | ||
} | ||
// This function needs to be loaded after the DEBUG env variable has been set | ||
const converter_1 = require("./converter"); | ||
async function sol2uml() { | ||
let fileFolderAddress; | ||
if (program.args.length === 0) { | ||
fileFolderAddress = process.cwd(); | ||
.addOption(new commander_1.Option('-d, --depth <value>', 'depth of connected classes to the base contracts. 1 will only show directly connected contracts, interfaces, libraries, structs and enums.').default('100', 'all')) | ||
.option('-c, --clusterFolders', 'cluster contracts into source folders', false) | ||
.option('-hv, --hideVariables', 'hide variables from contracts, interfaces, structs and enums', false) | ||
.option('-hf, --hideFunctions', 'hide functions from contracts, interfaces and libraries', false) | ||
.option('-hp, --hidePrivates', 'hide private and internal attributes and operators', false) | ||
.option('-he, --hideEnums', 'hide enum types', false) | ||
.option('-hs, --hideStructs', 'hide data structures', false) | ||
.option('-hl, --hideLibraries', 'hide libraries', false) | ||
.option('-hi, --hideInterfaces', 'hide interfaces', false) | ||
.option('-ha, --hideAbstracts', 'hide abstract contracts', false) | ||
.option('-hn, --hideFilename', 'hide relative path and file name', false) | ||
.action(async (fileFolderAddress, options, command) => { | ||
try { | ||
const combinedOptions = { | ||
...command.parent._optionValues, | ||
...options, | ||
}; | ||
const { umlClasses } = await parserGeneral_1.parserUmlClasses(fileFolderAddress, combinedOptions); | ||
let filteredUmlClasses = umlClasses; | ||
if (options.baseContractNames) { | ||
const baseContractNames = options.baseContractNames.split(','); | ||
filteredUmlClasses = filterClasses_1.classesConnectedToBaseContracts(umlClasses, baseContractNames, options.depth); | ||
} | ||
const dotString = converterClasses2Dot_1.convertUmlClasses2Dot(filteredUmlClasses, combinedOptions.clusterFolders, combinedOptions); | ||
await writerFiles_1.writeOutputFiles(dotString, fileFolderAddress, combinedOptions.outputFormat, combinedOptions.outputFileName); | ||
debug(`Finished generating UML`); | ||
} | ||
else { | ||
fileFolderAddress = program.args[0]; | ||
catch (err) { | ||
console.error(`Failed to generate UML diagram ${err.message}`); | ||
} | ||
let umlClasses; | ||
if (fileFolderAddress.match(/^0x([A-Fa-f0-9]{40})$/)) { | ||
debug(`argument ${fileFolderAddress} is an Ethereum address so checking Etherscan for the verified source code`); | ||
const etherscanApiKey = options.etherscanApiKey || 'ZAD4UI2RCXCQTP38EXS3UY2MPHFU5H9KB1'; | ||
const etherscanParser = new etherscanParser_1.EtherscanParser(etherscanApiKey, options.network); | ||
// If output is Solidity code | ||
if (options.outputFormat === 'sol') { | ||
const solidityCode = await etherscanParser.getSolidityCode(fileFolderAddress); | ||
// Write Solidity to the contract address | ||
converter_1.writeSolidity(solidityCode, fileFolderAddress); | ||
return; | ||
}); | ||
program | ||
.command('storage') | ||
.description('output a contracts storage slots') | ||
.argument('<fileFolderAddress>', 'file name, base folder or contract address') | ||
.option('-c, --contractName <value>', 'Contract name in local Solidity files. Not needed when using an address as the first argument.') | ||
// .option('-d, --data', 'gets the data in the storage slots') | ||
.action(async (fileFolderAddress, options, command) => { | ||
try { | ||
const combinedOptions = { | ||
...command.parent._optionValues, | ||
...options, | ||
}; | ||
const { umlClasses, contractName } = await parserGeneral_1.parserUmlClasses(fileFolderAddress, combinedOptions); | ||
const filteredUmlClasses = filterClasses_1.classesConnectedToBaseContracts(umlClasses, [combinedOptions.contractName || contractName]); | ||
const storageObjects = converterClasses2Storage_1.convertClasses2StorageObjects(combinedOptions.contractName || contractName, filteredUmlClasses); | ||
if (regEx_1.isAddress(fileFolderAddress)) { | ||
// The first object is the contract | ||
storageObjects[0].address = fileFolderAddress; | ||
} | ||
umlClasses = await etherscanParser.getUmlClasses(fileFolderAddress); | ||
debug(storageObjects); | ||
const dotString = converterStorage2Dot_1.convertStorage2Dot(storageObjects); | ||
await writerFiles_1.writeOutputFiles(dotString, fileFolderAddress, combinedOptions.outputFormat, combinedOptions.outputFileName); | ||
} | ||
else { | ||
const depthLimit = parseInt(options.depthLimit); | ||
if (isNaN(depthLimit)) { | ||
console.error(`depthLimit option must be an integer. Not ${options.depthLimit}`); | ||
process.exit(1); | ||
} | ||
const filesFolders = fileFolderAddress.split(','); | ||
let ignoreFilesFolders = options.ignoreFilesOrFolders | ||
? options.ignoreFilesOrFolders.split(',') | ||
: []; | ||
umlClasses = await fileParser_1.parseUmlClassesFromFiles(filesFolders, ignoreFilesFolders, depthLimit); | ||
catch (err) { | ||
console.error(`Failed to generate storage diagram ${err.message}`); | ||
} | ||
let filteredUmlClasses = umlClasses; | ||
if (options.baseContractNames) { | ||
const baseContractNames = options.baseContractNames.split(','); | ||
filteredUmlClasses = contractFilter_1.classesConnectedToBaseContracts(umlClasses, baseContractNames); | ||
} | ||
converter_1.generateFilesFromUmlClasses(filteredUmlClasses, fileFolderAddress, options.outputFormat, options.outputFileName, options.clusterFolders, { | ||
hideAttributes: options.hideAttributes, | ||
hideOperators: options.hideOperators, | ||
hideEnums: options.hideEnums, | ||
hideStructs: options.hideStructs, | ||
hideLibraries: options.hideLibraries, | ||
hideInterfaces: options.hideInterfaces, | ||
hideInternals: options.hideInternals, | ||
}).then(() => { | ||
debug(`Finished`); | ||
}); | ||
} | ||
try { | ||
sol2uml(); | ||
} | ||
catch (err) { | ||
console.error(`Failed to generate UML diagram ${err.message}`); | ||
} | ||
}); | ||
program | ||
.command('flatten') | ||
.description('get all verified source code for a contract from the Blockchain explorer into one local file') | ||
.argument('<contractAddress>', 'Contract address') | ||
.action(async (contractAddress, options, command) => { | ||
debug(`About to flatten ${contractAddress}`); | ||
const combinedOptions = { | ||
...command.parent._optionValues, | ||
...options, | ||
}; | ||
const etherscanParser = new parserEtherscan_1.EtherscanParser(combinedOptions.apiKey, combinedOptions.network); | ||
const { solidityCode, contractName } = await etherscanParser.getSolidityCode(contractAddress); | ||
// Write Solidity to the contract address | ||
const outputFilename = combinedOptions.outputFileName || contractName; | ||
await writerFiles_1.writeSolidity(solidityCode, outputFilename); | ||
}); | ||
program.on('option:verbose', () => { | ||
debugControl.enable('sol2uml'); | ||
debug('verbose on'); | ||
}); | ||
const main = async () => { | ||
await program.parseAsync(process.argv); | ||
}; | ||
main(); | ||
//# sourceMappingURL=sol2uml.js.map |
@@ -25,5 +25,8 @@ export declare enum Visibility { | ||
} | ||
export interface Parameter { | ||
name?: string; | ||
type: string; | ||
export declare enum AttributeType { | ||
Elementary = 0, | ||
UserDefined = 1, | ||
Function = 2, | ||
Array = 3, | ||
Mapping = 4 | ||
} | ||
@@ -34,3 +37,9 @@ export interface Attribute { | ||
type?: string; | ||
attributeType?: AttributeType; | ||
compiled?: boolean; | ||
} | ||
export interface Parameter { | ||
name?: string; | ||
type: string; | ||
} | ||
export interface Operator extends Attribute { | ||
@@ -58,5 +67,4 @@ stereotype?: OperatorStereotype; | ||
stereotype?: ClassStereotype; | ||
enums?: { | ||
[name: string]: string[]; | ||
}; | ||
enums?: number[]; | ||
structs?: number[]; | ||
attributes?: Attribute[]; | ||
@@ -78,8 +86,4 @@ operators?: Operator[]; | ||
operators: Operator[]; | ||
enums: { | ||
[name: string]: string[]; | ||
}; | ||
structs: { | ||
[name: string]: Parameter[]; | ||
}; | ||
enums: number[]; | ||
structs: number[]; | ||
associations: { | ||
@@ -90,2 +94,7 @@ [name: string]: Association; | ||
addAssociation(association: Association): void; | ||
/** | ||
* Gets the immediate parent contracts this class inherits from. | ||
* Does not include any grand parent associations. That has to be done recursively. | ||
*/ | ||
getParentContracts(): Association[]; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.UmlClass = exports.ReferenceType = exports.OperatorStereotype = exports.ClassStereotype = exports.Visibility = void 0; | ||
exports.UmlClass = exports.ReferenceType = exports.AttributeType = exports.OperatorStereotype = exports.ClassStereotype = exports.Visibility = void 0; | ||
var Visibility; | ||
@@ -31,2 +31,10 @@ (function (Visibility) { | ||
})(OperatorStereotype = exports.OperatorStereotype || (exports.OperatorStereotype = {})); | ||
var AttributeType; | ||
(function (AttributeType) { | ||
AttributeType[AttributeType["Elementary"] = 0] = "Elementary"; | ||
AttributeType[AttributeType["UserDefined"] = 1] = "UserDefined"; | ||
AttributeType[AttributeType["Function"] = 2] = "Function"; | ||
AttributeType[AttributeType["Array"] = 3] = "Array"; | ||
AttributeType[AttributeType["Mapping"] = 4] = "Mapping"; | ||
})(AttributeType = exports.AttributeType || (exports.AttributeType = {})); | ||
var ReferenceType; | ||
@@ -41,4 +49,4 @@ (function (ReferenceType) { | ||
this.operators = []; | ||
this.enums = {}; | ||
this.structs = {}; | ||
this.enums = []; | ||
this.structs = []; | ||
this.associations = {}; | ||
@@ -72,2 +80,11 @@ if (!properties || !properties.name) { | ||
} | ||
/** | ||
* Gets the immediate parent contracts this class inherits from. | ||
* Does not include any grand parent associations. That has to be done recursively. | ||
*/ | ||
getParentContracts() { | ||
return Object.values(this.associations).filter((association) => association.realization && | ||
association.targetUmlClassStereotype !== | ||
ClassStereotype.Interface); | ||
} | ||
} | ||
@@ -74,0 +91,0 @@ exports.UmlClass = UmlClass; |
{ | ||
"name": "sol2uml", | ||
"version": "1.1.29", | ||
"version": "2.0.0-beta.1", | ||
"description": "Unified Modeling Language (UML) class diagram generator for Solidity contracts", | ||
@@ -39,4 +39,4 @@ "main": "./lib/index.js", | ||
"prettier": "^2.3.2", | ||
"ts-jest": "^27.0.4", | ||
"ts-node": "^10.1.0", | ||
"ts-jest": "^27.0.5", | ||
"ts-node": "^10.2.1", | ||
"typescript": "^4.3.5" | ||
@@ -43,0 +43,0 @@ }, |
154
README.md
@@ -36,8 +36,37 @@ # Solidity 2 UML | ||
To see the usage options | ||
``` | ||
$ sol2uml -h | ||
Usage: sol2uml <fileFolderAddress> [options] | ||
$ sol2uml --help | ||
Usage: sol2uml [subcommand] <options> | ||
The three subcommands: | ||
* class: Generates a UML class diagram from Solidity source code. default | ||
* storage: Generates a diagram of a contract's storage slots. | ||
* flatten: Pulls verified source files from a Blockchain explorer into one, flat, local Solidity file. | ||
The Solidity code can be pulled from verified source code on Blockchain explorers like Etherscan or from local Solidity files. | ||
Options: | ||
-sf, --subfolders <value> number of subfolders that will be recursively searched for Solidity files. (default: all) | ||
-f, --outputFormat <value> output file format. (choices: "svg", "png", "dot", "all", default: "svg") | ||
-o, --outputFileName <value> output file name | ||
-i, --ignoreFilesOrFolders <filesOrFolders> comma separated list of files or folders to ignore | ||
-n, --network <network> Ethereum network (choices: "mainnet", "polygon", "bsc", "arbitrum", "ropsten", "kovan", "rinkeby", "goerli", default: "mainnet") | ||
-k, --apiKey <key> Etherscan, Polygonscan or BscScan API key | ||
-v, --verbose run with debugging statements (default: false) | ||
-h, --help display help for command | ||
Commands: | ||
class [options] [fileFolderAddress] Generates a UML class diagram from Solidity source code. | ||
storage [options] <fileFolderAddress> output a contracts storage slots | ||
flatten <contractAddress> get all verified source code for a contract from the Blockchain explorer into one local file | ||
help [command] display help for command | ||
``` | ||
### Class usage | ||
``` | ||
$sol2uml class --help | ||
Usage: sol2uml class <fileFolderAddress> [options] | ||
Generates UML diagrams from Solidity source code. | ||
If no file, folder or address is passes as the first argument, the working folder is used. | ||
@@ -51,25 +80,60 @@ When a folder is used, all *.sol files are found in that folder and all sub folders. | ||
Generates a UML class diagram from Solidity source code. | ||
Arguments: | ||
fileFolderAddress file name, base folder or contract address (default: "/Users/nicholasaddison/Documents/workspaces/sol2uml") | ||
Options: | ||
-b, --baseContractNames <value> only output contracts connected to these comma separated base contract names | ||
-f, --outputFormat <value> output file format: svg, png, sol, dot or all (default: "svg") | ||
-o, --outputFileName <value> output file name | ||
-d, --depthLimit <depth> number of sub folders that will be recursively searched for Solidity files. Default -1 is unlimited (default: -1) | ||
-i, --ignoreFilesOrFolders <filesOrFolders> comma separated list of files or folders to ignore | ||
-n, --network <network> mainnet, polygon, bsc, ropsten, kovan, rinkeby or goerli (default: "mainnet") | ||
-a, --hideAttributes hide class and interface attributes | ||
-p, --hideOperators hide class and interface operators/functions | ||
-e, --hideEnums hide enum types | ||
-s, --hideStructs hide data structures | ||
-l, --hideLibraries hide libraries | ||
-t, --hideInterfaces hide interfaces | ||
-r, --hideInternals hide private and internal attributes and operators | ||
-k, --etherscanApiKey <key> Etherscan API Key | ||
-c, --clusterFolders cluster contracts into source folders | ||
-v, --verbose run with debugging statements | ||
-h, --help output usage information | ||
-b, --baseContractNames <value> only output contracts connected to these comma separated base contract names | ||
-d, --depth <value> depth of connected classes to the base contracts. 1 will only show directly connected contracts, interfaces, libraries, structs and enums. (default: all) | ||
-c, --clusterFolders cluster contracts into source folders (default: false) | ||
-hv, --hideVariables hide variables from contracts, interfaces, structs and enums (default: false) | ||
-hf, --hideFunctions hide functions from contracts, interfaces and libraries (default: false) | ||
-hp, --hidePrivates hide private and internal attributes and operators (default: false) | ||
-he, --hideEnums hide enum types (default: false) | ||
-hs, --hideStructs hide data structures (default: false) | ||
-hl, --hideLibraries hide libraries (default: false) | ||
-hi, --hideInterfaces hide interfaces (default: false) | ||
-ha, --hideAbstracts hide abstract contracts (default: false) | ||
-hn, --hideFilename hide relative path and file name (default: false) | ||
-h, --help display help for command | ||
``` | ||
### Storage usage | ||
``` | ||
Usage: sol2uml storage [options] <fileFolderAddress> | ||
output a contracts storage slots | ||
Arguments: | ||
fileFolderAddress file name, base folder or contract address | ||
Options: | ||
-c, --contractName <value> Contract name in local Solidity files. Not needed when using an address as the first argument. | ||
-h, --help display help for command | ||
``` | ||
### Flatten usage | ||
``` | ||
$sol2uml flatten --help | ||
Usage: sol2uml flatten [options] <contractAddress> | ||
get all verified source code for a contract from the Blockchain explorer into one local file | ||
Arguments: | ||
contractAddress Contract address | ||
Options: | ||
-h, --help display help for command | ||
``` | ||
## UML Class diagram examples | ||
To generate a diagram of all contracts under the contracts folder and its sub folders | ||
```bash | ||
sol2uml ./contracts | ||
sol2uml class ./contracts | ||
``` | ||
@@ -79,3 +143,3 @@ | ||
```bash | ||
sol2uml 0x8d12A197cB00D4747a1fe03395095ce2A5CC6819 | ||
sol2uml class 0x8d12A197cB00D4747a1fe03395095ce2A5CC6819 | ||
``` | ||
@@ -85,3 +149,3 @@ | ||
```bash | ||
sol2uml 0xa19833bd291b66aB0E17b9C6d46D2Ec5fEC15190 -n ropsten | ||
sol2uml class 0xa19833bd291b66aB0E17b9C6d46D2Ec5fEC15190 -n ropsten | ||
``` | ||
@@ -91,3 +155,3 @@ | ||
```bash | ||
sol2uml path/to/contracts/root/folder -o ./outputFile.svg | ||
sol2uml class path/to/contracts/root/folder -o ./outputFile.svg | ||
``` | ||
@@ -97,3 +161,3 @@ | ||
```bash | ||
sol2uml path/to/contracts/root/folder/solidity/file.sol -f png -o ./someFile.png | ||
sol2uml class path/to/contracts/root/folder/solidity/file.sol -f png -o ./someFile.png | ||
``` | ||
@@ -103,3 +167,3 @@ | ||
```bash | ||
sol2uml ./contracts,node_modules/openzeppelin-solidity -f all -v | ||
sol2uml class ./contracts,node_modules/openzeppelin-solidity -f all -v | ||
``` | ||
@@ -109,29 +173,7 @@ | ||
```bash | ||
sol2uml -i solparse,@solidity-parser,ethlint | ||
sol2uml class -i solparse,@solidity-parser,ethlint | ||
``` | ||
## Application Programming Interface (API) | ||
# UML Class Diagram Syntax | ||
The main function that parses Solidity source code from files or files in folders is [parseUmlClassesFromFiles](./lib/fileParser.d.ts#L3). This returns an array of UML class objects. | ||
[EtherscanParser](./lib/etherscanParser.d.ts#L5) is a class that parses Etherscan's verified Solidity source code for a contract. For example | ||
```ts | ||
import { convertUmlClassesToSvg, EtherscanParser } from 'sol2uml' | ||
async function generateSvg() { | ||
const etherscanParser = new EtherscanParser() | ||
// get the verified source code from Etherscan for the contract address and | ||
// parse Solidity into UML class objects | ||
const umlClasses = await etherscanParser.getUmlClasses('0xf5dce57282a584d2746faf1593d3121fcac444dc') | ||
// Convert UML classes to a svg string | ||
const svg = await convertUmlClassesToSvg(umlClasses) | ||
} | ||
``` | ||
[generateFilesFromUmlClasses](./lib/converter.d.ts#L3) is used to write the dot, svg and png files from an array of UML class objects. | ||
# UML Syntax | ||
Good online resources for learning UML | ||
@@ -165,5 +207,5 @@ * [UML 2 Class Diagramming Guidelines](http://www.agilemodeling.com/style/classDiagram.htm) | ||
- Solid lines for | ||
- link the contract types of storage (state) variables. This can be linked to contracts, interfaces or libraries. | ||
- link the contract types of storage (state) variables. This can be linked to contracts, interfaces, libraries or file level structs and enums. | ||
- generalisations of contracts and abstract contracts. | ||
- aggregated structs and enums | ||
- aggregated contract level structs and enums. | ||
- Dashed lines for | ||
@@ -176,4 +218,10 @@ - generalisations of interfaces. | ||
- An open arrow head for storage or memory variable dependencies | ||
- A diamond tail for aggregations of structs and enums | ||
- A diamond tail for aggregations of contract level structs and enums | ||
# Version 2.x changes | ||
The biggest change with 2.x is the introduction of subcommands as sol2uml can now draw contract storage diagrams. | ||
See [version 2.x](./version2.md) for a list of changes from 1.x. | ||
# Contribution | ||
@@ -180,0 +228,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
112580
31
2258
244
2
1