sol2uml 2.3.1 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -3
- package/lib/diff.d.ts +7 -0
- package/lib/diff.js +188 -0
- package/lib/filterClasses.js +3 -2
- package/lib/parserEtherscan.js +3 -1
- package/lib/sol2uml.js +49 -4
- package/lib/utils/diff.d.ts +0 -0
- package/lib/utils/diff.js +1 -0
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -49,6 +49,7 @@ The three subcommands:
|
|
|
49
49
|
* class: Generates a UML class diagram from Solidity source code. default
|
|
50
50
|
* storage: Generates a diagram of a contract's storage slots.
|
|
51
51
|
* flatten: Merges verified source files from a Blockchain explorer into one local file.
|
|
52
|
+
* diff: Compares the flattened Solidity code from a Blockchain explorer for two contracts.
|
|
52
53
|
|
|
53
54
|
The Solidity code can be pulled from verified source code on Blockchain explorers like Etherscan or from local Solidity files.
|
|
54
55
|
|
|
@@ -73,7 +74,7 @@ Commands:
|
|
|
73
74
|
### Class usage
|
|
74
75
|
|
|
75
76
|
```
|
|
76
|
-
Usage: sol2uml class <fileFolderAddress>
|
|
77
|
+
Usage: sol2uml class [options] <fileFolderAddress>
|
|
77
78
|
|
|
78
79
|
Generates UML diagrams from Solidity source code.
|
|
79
80
|
|
|
@@ -114,7 +115,7 @@ Options:
|
|
|
114
115
|
### Storage usage
|
|
115
116
|
|
|
116
117
|
```
|
|
117
|
-
Usage: sol2uml storage <fileFolderAddress>
|
|
118
|
+
Usage: sol2uml storage [options] <fileFolderAddress>
|
|
118
119
|
|
|
119
120
|
WARNING: sol2uml does not use the Solidity compiler so may differ with solc. A known example is fixed-sized arrays declared with an expression will fail to be sized.
|
|
120
121
|
|
|
@@ -136,7 +137,7 @@ Options:
|
|
|
136
137
|
### Flatten usage
|
|
137
138
|
|
|
138
139
|
```
|
|
139
|
-
Usage: sol2uml flatten <contractAddress>
|
|
140
|
+
Usage: sol2uml flatten <contractAddress>
|
|
140
141
|
|
|
141
142
|
In order for the merged code to compile, the following is done:
|
|
142
143
|
1. pragma solidity is set using the compiler of the verified contract.
|
|
@@ -154,6 +155,28 @@ Options:
|
|
|
154
155
|
-h, --help display help for command
|
|
155
156
|
```
|
|
156
157
|
|
|
158
|
+
### Diff usage
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
Usage: sol2uml diff [options] <addressA> <addressB>
|
|
162
|
+
|
|
163
|
+
The results show the comparision of contract A to B.
|
|
164
|
+
The green sections are additions to contract B that are not in contract A.
|
|
165
|
+
The red sections are removals from contract A that are not in contract B.
|
|
166
|
+
The line numbers are from contract B. There are no line numbers for the red sections as they are not in contract B.
|
|
167
|
+
|
|
168
|
+
Compare verified Solidity code differences between two contracts.
|
|
169
|
+
|
|
170
|
+
Arguments:
|
|
171
|
+
addressA Contract address in hexadecimal format with a 0x prefix.
|
|
172
|
+
addressB Contract address in hexadecimal format with a 0x prefix.
|
|
173
|
+
|
|
174
|
+
Options:
|
|
175
|
+
-l, --lineBuffer <value> Minimum number a lines before and after changes (default: "4")
|
|
176
|
+
-s, --saveFiles Save the flattened contract code to the filesystem. The file names will be the contract address with a .sol extension. (default: false)
|
|
177
|
+
-h, --help display help for command
|
|
178
|
+
```
|
|
179
|
+
|
|
157
180
|
## UML Class diagram examples
|
|
158
181
|
|
|
159
182
|
To generate a diagram of all contracts under the contracts folder and its sub folders
|
package/lib/diff.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compares code using Google's diff_match_patch and displays the results in the console.
|
|
3
|
+
* @param codeA
|
|
4
|
+
* @param codeB
|
|
5
|
+
* @param lineBuff the number of lines to display before and after each change.
|
|
6
|
+
*/
|
|
7
|
+
export declare const diffCode: (codeA: string, codeB: string, lineBuff: number) => void;
|
package/lib/diff.js
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.diffCode = void 0;
|
|
27
|
+
const diff_match_patch_1 = __importStar(require("diff-match-patch"));
|
|
28
|
+
const clc = require('cli-color');
|
|
29
|
+
const SkippedLinesMarker = `\n---`;
|
|
30
|
+
/**
|
|
31
|
+
* Compares code using Google's diff_match_patch and displays the results in the console.
|
|
32
|
+
* @param codeA
|
|
33
|
+
* @param codeB
|
|
34
|
+
* @param lineBuff the number of lines to display before and after each change.
|
|
35
|
+
*/
|
|
36
|
+
const diffCode = (codeA, codeB, lineBuff) => {
|
|
37
|
+
// @ts-ignore
|
|
38
|
+
const dmp = new diff_match_patch_1.default();
|
|
39
|
+
const diff = dmp.diff_main(codeA, codeB);
|
|
40
|
+
dmp.diff_cleanupSemantic(diff);
|
|
41
|
+
const linesB = countLines(codeB) + 1;
|
|
42
|
+
diff_pretty(diff, linesB, lineBuff);
|
|
43
|
+
};
|
|
44
|
+
exports.diffCode = diffCode;
|
|
45
|
+
/**
|
|
46
|
+
* Convert a diff array into human readable for the console
|
|
47
|
+
* @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples.
|
|
48
|
+
* @param lines number of a lines in the second contract B
|
|
49
|
+
* @param lineBuff number of a lines to output before and after the change
|
|
50
|
+
*/
|
|
51
|
+
const diff_pretty = (diffs, lines, lineBuff = 2) => {
|
|
52
|
+
const linePad = lines.toString().length;
|
|
53
|
+
let output = '';
|
|
54
|
+
let diffIndex = 0;
|
|
55
|
+
let lineCount = 1;
|
|
56
|
+
const firstLineNumber = '1'.padStart(linePad) + ' ';
|
|
57
|
+
for (const diff of diffs) {
|
|
58
|
+
diffIndex++;
|
|
59
|
+
const initialLineNumber = diffIndex <= 1 ? firstLineNumber : '';
|
|
60
|
+
const op = diff[0]; // Operation (insert, delete, equal)
|
|
61
|
+
const text = diff[1]; // Text of change.
|
|
62
|
+
switch (op) {
|
|
63
|
+
case diff_match_patch_1.DIFF_INSERT:
|
|
64
|
+
// If first diff then we need to add the first line number
|
|
65
|
+
const linesInserted = addLineNumbers(text, lineCount, linePad);
|
|
66
|
+
output += initialLineNumber + clc.green(linesInserted);
|
|
67
|
+
lineCount += countLines(text);
|
|
68
|
+
break;
|
|
69
|
+
case diff_match_patch_1.DIFF_DELETE:
|
|
70
|
+
// zero start line means blank line numbers are used
|
|
71
|
+
const linesDeleted = addLineNumbers(text, 0, linePad);
|
|
72
|
+
output += initialLineNumber + clc.red(linesDeleted);
|
|
73
|
+
break;
|
|
74
|
+
case diff_match_patch_1.DIFF_EQUAL:
|
|
75
|
+
const eolPositions = findEOLPositions(text);
|
|
76
|
+
// If no changes yet
|
|
77
|
+
if (diffIndex <= 1) {
|
|
78
|
+
output += lastLines(text, eolPositions, lineBuff, linePad);
|
|
79
|
+
}
|
|
80
|
+
// if no more changes
|
|
81
|
+
else if (diffIndex === diffs.length) {
|
|
82
|
+
output += firstLines(text, eolPositions, lineBuff, lineCount, linePad);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
// else the first n lines and last n lines
|
|
86
|
+
output += firstAndLastLines(text, eolPositions, lineBuff, lineCount, linePad);
|
|
87
|
+
}
|
|
88
|
+
lineCount += eolPositions.length;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
output += '\n';
|
|
93
|
+
console.log(output);
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Used when there is no more changes left
|
|
97
|
+
*/
|
|
98
|
+
const firstLines = (text, eolPositions, lineBuff, lineStart, linePad) => {
|
|
99
|
+
const lines = text.slice(0, eolPositions[lineBuff]);
|
|
100
|
+
return addLineNumbers(lines, lineStart, linePad);
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Used before the first change
|
|
104
|
+
*/
|
|
105
|
+
const lastLines = (text, eolPositions, lineBuff, linePad) => {
|
|
106
|
+
const eolFrom = eolPositions.length - (lineBuff + 1);
|
|
107
|
+
let lines = text;
|
|
108
|
+
let lineCount = 1;
|
|
109
|
+
if (eolFrom >= 0) {
|
|
110
|
+
lines = eolFrom >= 0 ? text.slice(eolPositions[eolFrom] + 1) : text;
|
|
111
|
+
lineCount = eolFrom + 2;
|
|
112
|
+
}
|
|
113
|
+
const firstLineNumber = lineCount.toString().padStart(linePad) + ' ';
|
|
114
|
+
return firstLineNumber + addLineNumbers(lines, lineCount, linePad);
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Used between changes to show the lines after the last change and before the next change.
|
|
118
|
+
* @param text
|
|
119
|
+
* @param eolPositions
|
|
120
|
+
* @param lineBuff
|
|
121
|
+
* @param lineStart
|
|
122
|
+
* @param linePad
|
|
123
|
+
*/
|
|
124
|
+
const firstAndLastLines = (text, eolPositions, lineBuff, lineStart, linePad) => {
|
|
125
|
+
if (eolPositions.length <= 2 * lineBuff) {
|
|
126
|
+
return addLineNumbers(text, lineStart, linePad);
|
|
127
|
+
}
|
|
128
|
+
const endFirstLines = eolPositions[lineBuff];
|
|
129
|
+
const eolFrom = eolPositions.length - (lineBuff + 1);
|
|
130
|
+
const startLastLines = eolPositions[eolFrom];
|
|
131
|
+
if (startLastLines <= endFirstLines) {
|
|
132
|
+
return addLineNumbers(text, lineStart, linePad);
|
|
133
|
+
}
|
|
134
|
+
// Lines after the previous change
|
|
135
|
+
let lines = text.slice(0, endFirstLines);
|
|
136
|
+
let output = addLineNumbers(lines, lineStart, linePad);
|
|
137
|
+
output += SkippedLinesMarker;
|
|
138
|
+
// Lines before the next change
|
|
139
|
+
lines = text.slice(startLastLines);
|
|
140
|
+
const lineCount = lineStart + eolFrom;
|
|
141
|
+
output += addLineNumbers(lines, lineCount, linePad);
|
|
142
|
+
return output;
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Gets the positions of the end of lines in the string
|
|
146
|
+
* @param text
|
|
147
|
+
*/
|
|
148
|
+
const findEOLPositions = (text) => {
|
|
149
|
+
const eolPositions = [];
|
|
150
|
+
text.split('').forEach((c, i) => {
|
|
151
|
+
if (c === '\n') {
|
|
152
|
+
eolPositions.push(i);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
return eolPositions;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Counts the number of carriage returns in a string
|
|
159
|
+
* @param text
|
|
160
|
+
*/
|
|
161
|
+
const countLines = (text) => (text.match(/\n/g) || '').length;
|
|
162
|
+
/**
|
|
163
|
+
* Adds left padded line numbers to each line.
|
|
164
|
+
* @param text with the lines of code
|
|
165
|
+
* @param lineStart the line number of the first line in the text. If zero, then no lines numbers are added.
|
|
166
|
+
* @param linePad the width of the largest number which may not be in the text
|
|
167
|
+
*/
|
|
168
|
+
const addLineNumbers = (text, lineStart, linePad) => {
|
|
169
|
+
let lineCount = lineStart;
|
|
170
|
+
let textWithLineNumbers = '';
|
|
171
|
+
text.split('').forEach((c, i) => {
|
|
172
|
+
if (c === '\n') {
|
|
173
|
+
if (lineStart > 0) {
|
|
174
|
+
textWithLineNumbers += `\n${(++lineCount)
|
|
175
|
+
.toString()
|
|
176
|
+
.padStart(linePad)} `;
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
textWithLineNumbers += `\n${' '.repeat(linePad)} `;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
textWithLineNumbers += c;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
return textWithLineNumbers;
|
|
187
|
+
};
|
|
188
|
+
//# sourceMappingURL=diff.js.map
|
package/lib/filterClasses.js
CHANGED
|
@@ -99,11 +99,12 @@ const topologicalSortClasses = (umlClasses) => {
|
|
|
99
99
|
const sortedUmlClasses = sortedUmlClassIds.map((umlClassId) =>
|
|
100
100
|
// Lookup the UmlClass for each class id
|
|
101
101
|
umlClasses.find((umlClass) => umlClass.id === umlClassId));
|
|
102
|
-
|
|
102
|
+
// Filter out any unfound classes. This happens when diff sources the second contract.
|
|
103
|
+
return sortedUmlClasses.filter((umlClass) => umlClass !== undefined);
|
|
103
104
|
};
|
|
104
105
|
exports.topologicalSortClasses = topologicalSortClasses;
|
|
105
106
|
const loadDirectedAcyclicGraph = (umlClasses) => {
|
|
106
|
-
const directedAcyclicGraph = new js_graph_algorithms_1.DiGraph(
|
|
107
|
+
const directedAcyclicGraph = new js_graph_algorithms_1.DiGraph(umlClass_1.UmlClass.idCounter); // the number vertices in the graph
|
|
107
108
|
for (const sourceUmlClass of umlClasses) {
|
|
108
109
|
for (const association of Object.values(sourceUmlClass.associations)) {
|
|
109
110
|
// Find the first UML Class that matches the target class name
|
package/lib/parserEtherscan.js
CHANGED
|
@@ -147,7 +147,9 @@ class EtherscanParser {
|
|
|
147
147
|
// find any files that didn't have dependencies found
|
|
148
148
|
const nonDependentFiles = files.filter((f) => !dependentFilenames.includes(f.filename));
|
|
149
149
|
const nonDependentFilenames = nonDependentFiles.map((f) => f.filename);
|
|
150
|
-
|
|
150
|
+
if (nonDependentFilenames.length) {
|
|
151
|
+
debug(`Failed to find dependencies to files: ${nonDependentFilenames}`);
|
|
152
|
+
}
|
|
151
153
|
const solidityVersion = (0, regEx_1.parseSolidityVersion)(compilerVersion);
|
|
152
154
|
let solidityCode = `pragma solidity =${solidityVersion};\n`;
|
|
153
155
|
// output non dependent code before the dependent files just in case sol2uml missed some dependencies
|
package/lib/sol2uml.js
CHANGED
|
@@ -12,6 +12,8 @@ const regEx_1 = require("./utils/regEx");
|
|
|
12
12
|
const writerFiles_1 = require("./writerFiles");
|
|
13
13
|
const path_1 = require("path");
|
|
14
14
|
const squashClasses_1 = require("./squashClasses");
|
|
15
|
+
const diff_1 = require("./diff");
|
|
16
|
+
const clc = require('cli-color');
|
|
15
17
|
const program = new commander_1.Command();
|
|
16
18
|
const version = (0, path_1.basename)(__dirname) === 'lib'
|
|
17
19
|
? require('../package.json').version // used when run from compile js in /lib
|
|
@@ -25,7 +27,8 @@ program
|
|
|
25
27
|
sol2uml comes with three subcommands:
|
|
26
28
|
* class: Generates a UML class diagram from Solidity source code. (default)
|
|
27
29
|
* storage: Generates a diagram of a contract's storage slots.
|
|
28
|
-
* flatten: Merges verified
|
|
30
|
+
* flatten: Merges verified Solidity files from a Blockchain explorer into one local file.
|
|
31
|
+
* diff: Compares the flattened Solidity code from a Blockchain explorer for two contracts.
|
|
29
32
|
|
|
30
33
|
The Solidity code can be pulled from verified source code on Blockchain explorers like Etherscan or from local Solidity files.`)
|
|
31
34
|
.addOption(new commander_1.Option('-sf, --subfolders <value>', 'number of subfolders that will be recursively searched for Solidity files.').default('-1', 'all'))
|
|
@@ -43,7 +46,7 @@ The Solidity code can be pulled from verified source code on Blockchain explorer
|
|
|
43
46
|
program
|
|
44
47
|
.command('class', { isDefault: true })
|
|
45
48
|
.description('Generates a UML class diagram from Solidity source code.')
|
|
46
|
-
.usage(
|
|
49
|
+
.usage(`sol2uml [options] <fileFolderAddress>
|
|
47
50
|
|
|
48
51
|
Generates UML diagrams from Solidity source code.
|
|
49
52
|
|
|
@@ -111,7 +114,7 @@ If an Ethereum address with a 0x prefix is passed, the verified source code from
|
|
|
111
114
|
program
|
|
112
115
|
.command('storage')
|
|
113
116
|
.description("Visually display a contract's storage slots.")
|
|
114
|
-
.usage(
|
|
117
|
+
.usage(`[options] <fileFolderAddress>
|
|
115
118
|
|
|
116
119
|
WARNING: sol2uml does not use the Solidity compiler so may differ with solc. A known example is fixed-sized arrays declared with an expression will fail to be sized.`)
|
|
117
120
|
.argument('<fileFolderAddress>', 'file name, base folder or contract address')
|
|
@@ -170,7 +173,7 @@ WARNING: sol2uml does not use the Solidity compiler so may differ with solc. A k
|
|
|
170
173
|
program
|
|
171
174
|
.command('flatten')
|
|
172
175
|
.description('Merges verified source files for a contract from a Blockchain explorer into one local file.')
|
|
173
|
-
.usage(`<contractAddress>
|
|
176
|
+
.usage(`<contractAddress>
|
|
174
177
|
|
|
175
178
|
In order for the merged code to compile, the following is done:
|
|
176
179
|
1. pragma solidity is set using the compiler of the verified contract.
|
|
@@ -197,6 +200,48 @@ In order for the merged code to compile, the following is done:
|
|
|
197
200
|
process.exit(2);
|
|
198
201
|
}
|
|
199
202
|
});
|
|
203
|
+
program
|
|
204
|
+
.command('diff')
|
|
205
|
+
.description('Compare verified Solidity code differences between two contracts.')
|
|
206
|
+
.usage(`[options] <addressA> <addressB>
|
|
207
|
+
|
|
208
|
+
The results show the comparision of contract A to B.
|
|
209
|
+
The ${clc.green('green')} sections are additions to contract B that are not in contract A.
|
|
210
|
+
The ${clc.red('red')} sections are removals from contract A that are not in contract B.
|
|
211
|
+
The line numbers are from contract B. There are no line numbers for the red sections as they are not in contract B.`)
|
|
212
|
+
.argument('<addressA>', 'Contract address in hexadecimal format with a 0x prefix.')
|
|
213
|
+
.argument('<addressB>', 'Contract address in hexadecimal format with a 0x prefix.')
|
|
214
|
+
.addOption(new commander_1.Option('-l, --lineBuffer <value>', 'Minimum number a lines before and after changes').default('4'))
|
|
215
|
+
.option('-s, --saveFiles', 'Save the flattened contract code to the filesystem. The file names will be the contract address with a .sol extension.', false)
|
|
216
|
+
.action(async (addressA, addressB, options, command) => {
|
|
217
|
+
try {
|
|
218
|
+
debug(`About to diff ${addressA} and ${addressB}`);
|
|
219
|
+
const combinedOptions = {
|
|
220
|
+
...command.parent._optionValues,
|
|
221
|
+
...options,
|
|
222
|
+
};
|
|
223
|
+
// Diff solidity code
|
|
224
|
+
const lineBuffer = parseInt(options.lineBuffer);
|
|
225
|
+
if (isNaN(lineBuffer))
|
|
226
|
+
throw Error(`Invalid line buffer "${options.lineBuffer}". Must be a number`);
|
|
227
|
+
const etherscanParser = new parserEtherscan_1.EtherscanParser(combinedOptions.apiKey, combinedOptions.network);
|
|
228
|
+
// Get verified Solidity code from Etherscan and flatten
|
|
229
|
+
const { solidityCode: codeA, contractName: contractNameA } = await etherscanParser.getSolidityCode(addressA);
|
|
230
|
+
const { solidityCode: codeB, contractName: contractNameB } = await etherscanParser.getSolidityCode(addressB);
|
|
231
|
+
console.log(`Difference between`);
|
|
232
|
+
console.log(`A. ${addressA} ${contractNameA} on ${combinedOptions.network}`);
|
|
233
|
+
console.log(`B. ${addressB} ${contractNameB} on ${combinedOptions.network}\n`);
|
|
234
|
+
(0, diff_1.diffCode)(codeA, codeB, lineBuffer);
|
|
235
|
+
if (options.saveFiles) {
|
|
236
|
+
await (0, writerFiles_1.writeSolidity)(codeA, addressA);
|
|
237
|
+
await (0, writerFiles_1.writeSolidity)(codeB, addressB);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
catch (err) {
|
|
241
|
+
console.error(err);
|
|
242
|
+
process.exit(2);
|
|
243
|
+
}
|
|
244
|
+
});
|
|
200
245
|
program.on('option:verbose', () => {
|
|
201
246
|
debugControl.enable('sol2uml,axios');
|
|
202
247
|
debug('verbose on');
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=diff.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sol2uml",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Solidity contract visualisation tool.",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -23,15 +23,18 @@
|
|
|
23
23
|
"@solidity-parser/parser": "^0.14.5",
|
|
24
24
|
"axios": "^1.2.1",
|
|
25
25
|
"axios-debug-log": "^1.0.0",
|
|
26
|
+
"cli-color": "^2.0.3",
|
|
26
27
|
"commander": "^9.4.1",
|
|
27
28
|
"convert-svg-to-png": "^0.6.4",
|
|
28
29
|
"debug": "^4.3.4",
|
|
30
|
+
"diff-match-patch": "^1.0.5",
|
|
29
31
|
"ethers": "^5.7.2",
|
|
30
32
|
"js-graph-algorithms": "^1.0.18",
|
|
31
33
|
"klaw": "^4.0.1"
|
|
32
34
|
},
|
|
33
35
|
"devDependencies": {
|
|
34
36
|
"@openzeppelin/contracts": "4.8.0",
|
|
37
|
+
"@types/diff-match-patch": "^1.0.32",
|
|
35
38
|
"@types/jest": "^29.2.4",
|
|
36
39
|
"@types/klaw": "^3.0.3",
|
|
37
40
|
"jest": "^29.3.1",
|