0.1.12 release
This commit is contained in:
Родитель
a40021cf4f
Коммит
2ec6e9d90b
20
CHANGELOG.md
20
CHANGELOG.md
|
@ -1,9 +1,27 @@
|
|||
# Change Log
|
||||
|
||||
All notable changes to the "azureblockchain" extension will be documented in this file.
|
||||
All notable changes to the "azure blockchain" extension will be documented in this file.
|
||||
|
||||
|
||||
|
||||
## 0.1.12
|
||||
|
||||
- Deployments from external truffle boxes can now deploy to Azure Blockchain Service
|
||||
- Additional context menu for deployed contract bytecode (transaction bytecode)
|
||||
- Fix on Mocks category for OpenZeppelin to remove the dead link for not existent docs
|
||||
- Better handling of OpenZeppelin when multiple categories are downloaded.
|
||||
- Fix misspelling of OpenZeppelin on the welcome page.
|
||||
|
||||
## 0.1.11
|
||||
|
||||
- Fixed issue with Logic App generation JSON schema
|
||||
- Added Contract UI support for contracts deployed on Azure Blockchain Service
|
||||
- Updated deprecated Truffle NPM packages
|
||||
- Bumped HD wallet provider to latest Truffle version
|
||||
- Minimized output channel logs
|
||||
- Fixed output channel issue which shows JavaScript object after contract migration
|
||||
- Preview features added for token (TTI compliant) generation were added.
|
||||
|
||||
## 0.1.10
|
||||
|
||||
- Fixed Drizzle error handling issues
|
||||
|
|
34263
NOTICE.txt
34263
NOTICE.txt
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -40,15 +40,15 @@
|
|||
"style-loader": "^0.23.1",
|
||||
"url-loader": "^2.1.0",
|
||||
"webpack": "^4.38.0",
|
||||
"webpack-cli": "^3.3.6",
|
||||
"webpack-plugin-replace": "^1.2.0"
|
||||
"webpack-cli": "^3.3.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@drizzle/react-components": "^1.5.1",
|
||||
"@drizzle/react-plugin": "^1.5.1",
|
||||
"@drizzle/store": "^1.5.1",
|
||||
"@material-ui/core": "^4.2.1",
|
||||
"@material-ui/icons": "^4.2.1",
|
||||
"drizzle": "^1.4.0",
|
||||
"drizzle-react": "^1.3.0",
|
||||
"drizzle-react-components": "^1.4.0",
|
||||
"@truffle/hdwallet-provider": "^1.0.23",
|
||||
"react": "^16.10.2",
|
||||
"react-dom": "^16.10.2"
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { Constants } from './constants';
|
||||
import { Container } from '@material-ui/core';
|
||||
import { DrizzleContext } from 'drizzle-react';
|
||||
import { DrizzleContext } from '@drizzle/react-plugin';
|
||||
import HDWalletProvider from '@truffle/hdwallet-provider';
|
||||
import { IPC } from 'services';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
@ -83,11 +85,29 @@ class App extends React.Component {
|
|||
drizzle.deleteAllContracts();
|
||||
|
||||
if (provider) {
|
||||
const { WebsocketProvider } = drizzle.web3.providers;
|
||||
const host = new URL(Url.normalize(provider.host));
|
||||
|
||||
host.protocol = 'ws';
|
||||
let web3Provider;
|
||||
|
||||
drizzle.web3.setProvider(host.toString());
|
||||
if (
|
||||
Constants.regexps.providerTypes.azure.test(host.toString()) &&
|
||||
provider.options &&
|
||||
provider.options.mnemonic
|
||||
) {
|
||||
host.protocol = 'wss';
|
||||
host.port = 3300;
|
||||
|
||||
web3Provider = new HDWalletProvider(
|
||||
provider.options.mnemonic,
|
||||
new WebsocketProvider(host.toString()),
|
||||
);
|
||||
} else {
|
||||
host.protocol = 'ws';
|
||||
web3Provider = new WebsocketProvider(host.toString());
|
||||
}
|
||||
|
||||
drizzle.web3.setProvider(web3Provider);
|
||||
}
|
||||
|
||||
const address = contractInstance.address;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
import { createInputComponent } from '../factory/InputComponentFactory';
|
||||
import { newContextComponents } from 'drizzle-react-components';
|
||||
import { newContextComponents } from '@drizzle/react-components';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import { Container } from '@material-ui/core';
|
||||
import { deepEqual } from 'helpers';
|
||||
import { DrizzleContext } from 'drizzle-react';
|
||||
import { DrizzleContext } from '@drizzle/react-plugin';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { DrizzleContext } from 'drizzle-react';
|
||||
import { DrizzleContext } from '@drizzle/react-plugin';
|
||||
import { FileCopy } from '@material-ui/icons';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
|
|
@ -52,4 +52,10 @@ export class Constants {
|
|||
},
|
||||
arrayTypeRegexp: /\w*\[\d*\]/g,
|
||||
};
|
||||
|
||||
static regexps = {
|
||||
providerTypes: {
|
||||
azure: /blockchain.azure.com/i
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,50 +3,16 @@
|
|||
|
||||
import App from './App';
|
||||
import { contractEventNotifier } from 'middlewares';
|
||||
import { DrizzleContext } from 'drizzle-react';
|
||||
import { LocalStorage } from 'polyfills/localStorage';
|
||||
import { newContextComponents } from 'drizzle-react-components';
|
||||
import { DrizzleContext } from '@drizzle/react-plugin';
|
||||
import React from 'react';
|
||||
import { render } from 'react-dom';
|
||||
import { Drizzle, generateStore } from 'drizzle';
|
||||
|
||||
const storage = new LocalStorage();
|
||||
|
||||
window.ls = new Proxy(storage, {
|
||||
set: (_, prop, value) => {
|
||||
if (LocalStorage.prototype.hasOwnProperty(prop)) {
|
||||
storage[prop] = value;
|
||||
} else {
|
||||
storage.setItem(prop, value);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
get: (_, name) => {
|
||||
if (LocalStorage.prototype.hasOwnProperty(name)) {
|
||||
return storage[name];
|
||||
}
|
||||
if (storage.values.has(name)) {
|
||||
return storage.getItem(name);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
});
|
||||
import { Drizzle, generateStore } from '@drizzle/store';
|
||||
|
||||
Drizzle.prototype.deleteAllContracts = function () {
|
||||
Object.keys(this.contracts)
|
||||
.forEach(contractName => this.deleteContract(contractName));
|
||||
};
|
||||
|
||||
newContextComponents.ContractForm.prototype.handleInputChange = function (event) {
|
||||
const value = event.target.type === 'checkbox'
|
||||
? event.target.checked
|
||||
: event.target.value;
|
||||
this.setState({ [event.target.name]: value });
|
||||
};
|
||||
|
||||
const options = { contracts: [] };
|
||||
|
||||
const store = generateStore({
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { EventActions } from 'drizzle';
|
||||
import { EventActions } from '@drizzle/store';
|
||||
import { Notifications } from 'services';
|
||||
|
||||
export const contractEventNotifier = () => next => action => {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
import { Container } from '@material-ui/core';
|
||||
import { DrizzleContext } from 'drizzle-react';
|
||||
import { DrizzleContext } from '@drizzle/react-plugin';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
const path = require('path');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const ReplacePlugin = require('webpack-plugin-replace');
|
||||
const webpack = require('webpack');
|
||||
|
||||
module.exports = () => {
|
||||
|
@ -38,7 +37,6 @@ module.exports = () => {
|
|||
components: path.join(__dirname, './src/components'),
|
||||
constants: path.join(__dirname, './src/constants'),
|
||||
helpers: path.join(__dirname, './src/helpers'),
|
||||
polyfills: path.join(__dirname, './src/polyfills'),
|
||||
services: path.join(__dirname, './src/services'),
|
||||
views: path.join(__dirname, './src/views'),
|
||||
middlewares: path.join(__dirname, './src/middlewares'),
|
||||
|
@ -87,17 +85,6 @@ module.exports = () => {
|
|||
filename: '[name].css',
|
||||
allChunks: true,
|
||||
}),
|
||||
new ReplacePlugin({
|
||||
exclude: path.join(__dirname, 'src', 'index.js'),
|
||||
include: true,
|
||||
patterns: [{
|
||||
regex: /localStorage/g,
|
||||
value: 'ls'
|
||||
}],
|
||||
values: {
|
||||
ls: 'ls'
|
||||
}
|
||||
}),
|
||||
new webpack.optimize.AggressiveMergingPlugin(),
|
||||
]
|
||||
};
|
||||
|
|
43
package.json
43
package.json
|
@ -5,7 +5,7 @@
|
|||
"publisher": "AzBlockchain",
|
||||
"preview": true,
|
||||
"icon": "images/blockchain-service-logo.png",
|
||||
"version": "0.1.10",
|
||||
"version": "0.1.12",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/vscode-azure-blockchain-ethereum"
|
||||
|
@ -36,6 +36,7 @@
|
|||
"onCommand:azureBlockchainService.showWelcomePage",
|
||||
"onCommand:azureBlockchainService.refresh",
|
||||
"onCommand:contract.copyByteCode",
|
||||
"onCommand:contract.copyDeployedByteCode",
|
||||
"onCommand:contract.copyABI",
|
||||
"onCommand:truffle.createLocalUI",
|
||||
"onCommand:truffle.newSolidityProject",
|
||||
|
@ -54,6 +55,7 @@
|
|||
"onCommand:openZeppelin.addCategory",
|
||||
"onCommand:azureBlockchainService.signInToInfuraAccount",
|
||||
"onCommand:azureBlockchainService.signOutOfInfuraAccount",
|
||||
"onCommand:azureBlockchainService.generateToken",
|
||||
"onDebug"
|
||||
],
|
||||
"contributes": {
|
||||
|
@ -94,7 +96,12 @@
|
|||
},
|
||||
{
|
||||
"command": "contract.copyByteCode",
|
||||
"title": "Copy Contract Bytecode",
|
||||
"title": "Copy Constructor Bytecode",
|
||||
"category": "Azure Blockchain"
|
||||
},
|
||||
{
|
||||
"command": "contract.copyDeployedByteCode",
|
||||
"title": "Copy Transaction Bytecode",
|
||||
"category": "Azure Blockchain"
|
||||
},
|
||||
{
|
||||
|
@ -176,6 +183,11 @@
|
|||
"command": "openZeppelin.addCategory",
|
||||
"title": "Add contracts from OpenZeppelin",
|
||||
"category": "Azure Blockchain"
|
||||
},
|
||||
{
|
||||
"command": "azureBlockchainService.generateToken",
|
||||
"title": "Generate token",
|
||||
"category": "Azure Blockchain"
|
||||
}
|
||||
],
|
||||
"breakpoints": [
|
||||
|
@ -220,10 +232,18 @@
|
|||
"when": "resourceLangId == solidity",
|
||||
"command": "azureBlockchainService.generateReportPublishingWorkflows"
|
||||
},
|
||||
{
|
||||
"when": "false",
|
||||
"command": "azureBlockchainService.generateToken"
|
||||
},
|
||||
{
|
||||
"when": "false",
|
||||
"command": "contract.copyByteCode"
|
||||
},
|
||||
{
|
||||
"when": "false",
|
||||
"command": "contract.copyDeployedByteCode"
|
||||
},
|
||||
{
|
||||
"when": "false",
|
||||
"command": "contract.copyABI"
|
||||
|
@ -318,6 +338,11 @@
|
|||
"command": "contract.copyByteCode",
|
||||
"group": "9_copyFromContractGroup"
|
||||
},
|
||||
{
|
||||
"when": "resourceLangId == json",
|
||||
"command": "contract.copyDeployedByteCode",
|
||||
"group": "9_copyFromContractGroup"
|
||||
},
|
||||
{
|
||||
"when": "resourceLangId == json",
|
||||
"command": "contract.copyABI",
|
||||
|
@ -347,6 +372,11 @@
|
|||
"when": "resourceLangId == solidity",
|
||||
"command": "openZeppelin.addCategory",
|
||||
"group": "8_buildContractGroup"
|
||||
},
|
||||
{
|
||||
"when": "resourceLangId == solidity",
|
||||
"command": "azureBlockchainService.generateToken",
|
||||
"group": "8_buildContractGroup"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -453,7 +483,6 @@
|
|||
"clean": "npx rimraf -- ./out/*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@machinomy/types-ethereumjs-wallet": "^0.0.12",
|
||||
"@types/astring": "^1.3.0",
|
||||
"@types/estree": "^0.0.39",
|
||||
"@types/download": "^6.2.4",
|
||||
|
@ -492,6 +521,9 @@
|
|||
"webpack-cli": "^3.3.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@truffle/debug-utils": "1.0.19",
|
||||
"@truffle/debugger": "5.0.35",
|
||||
"@truffle/provider": "0.2.1",
|
||||
"abi-decoder": "^2.0.1",
|
||||
"acorn": "^6.1.1",
|
||||
"acorn-walk": "^6.1.1",
|
||||
|
@ -499,7 +531,6 @@
|
|||
"azure-arm-resource": "^7.3.0",
|
||||
"bip39": "^3.0.1",
|
||||
"download": "^7.1.0",
|
||||
"ethereumjs-wallet": "^0.6.3",
|
||||
"fs-extra": "^7.0.1",
|
||||
"hdkey": "^1.1.1",
|
||||
"ms-rest": "^2.5.0",
|
||||
|
@ -508,10 +539,6 @@
|
|||
"request": "^2.88.0",
|
||||
"request-promise": "^4.2.4",
|
||||
"semver": "^6.0.0",
|
||||
"truffle-contract": "4.0.30",
|
||||
"truffle-debug-utils": "1.0.18",
|
||||
"truffle-debugger": "5.0.25",
|
||||
"truffle-provider": "0.1.15",
|
||||
"uuid": "^3.3.2",
|
||||
"vscode-azureextensionui": "^0.25.1",
|
||||
"vscode-extension-telemetry": "^0.1.1"
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
margin: 10px 0 10px 0;
|
||||
}
|
||||
|
||||
.paragraph > div,
|
||||
#numberOfSubTokens {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.textInputMargin {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.generateButton {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.errorNotification {
|
||||
margin: 0;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.notificationForRequiredFields {
|
||||
border: 2px solid red;
|
||||
border-radius: 7px;
|
||||
width: fit-content;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
#customDetails {
|
||||
margin-top: 10px;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="{{root}}/resources/tokenui/generateToken.css">
|
||||
<script type="text/javascript" src="{{root}}/resources/welcome/jquery-3.3.1.min.js"></script>
|
||||
<script type="text/javascript" src="{{root}}/resources/tokenui/generateToken.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div id="title-area">
|
||||
<h1>Token generation</h1>
|
||||
</div>
|
||||
</header>
|
||||
<div>
|
||||
<div id="TokenGenerationForm">
|
||||
<div class="inputForm paragraph">
|
||||
<label>Please provide a name for your token.</label><br>
|
||||
<div>
|
||||
<input id="tokenName" type="text" placeholder="Token Name *">
|
||||
<div id="tokenNameValidationTip" class="hidden">
|
||||
<label class="errorNotification">Should be alphanumeric and from 1-255 characters.</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="selectionForm paragraph">
|
||||
<label>Please choose the token type.</label><br>
|
||||
<div id="tokenType">
|
||||
<label><input id="singleOrSolitary" type="radio" name="tokenType" value="false">Single/Solitary</label><br>
|
||||
<label><input id="compositeOrHybrid" type="radio" name="tokenType" value="true">Composite/Hybrid</label><br>
|
||||
<div id="selectionOfSubTokens" class="hidden">
|
||||
<label>How many sub tokens?</label><br>
|
||||
<div class="paragraph">
|
||||
<select id="numberOfSubTokens">
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
<option value="4">4</option>
|
||||
<option value="5">5</option>
|
||||
<option value="6">6</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="mainPropertiesAndBehaviorsToken">
|
||||
<label>Please choose properties and behaviors for your token.</label>
|
||||
|
||||
</div>
|
||||
<div id="propertiesAndBehaviorsSubTokens">
|
||||
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<label>Do you want to add custom details for your token (metadata such as SKU, issue date, place, etc)?</label><br>
|
||||
<div>
|
||||
<div id="addCustomDetails">
|
||||
<label><input id="yesAddCustomDetails" type="radio" name="addCustomDetails" value="true">Yes</label>
|
||||
<label><input id="noAddCustomDetails" type="radio" name="addCustomDetails" value="false">No</label>
|
||||
</div>
|
||||
<input class="textInputMargin hidden" id="customDetails" type="text" placeholder="Comma separated list">
|
||||
|
||||
<div id="customDetailsValidationTip" class="hidden">
|
||||
<label class="errorNotification">Should be comma separated list of symbols. Should be alphanumeric and from 1-255 characters.</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="generateButton" id="generateButton" type="submit">Generate</button>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,363 @@
|
|||
$(function() {
|
||||
main();
|
||||
});
|
||||
|
||||
function main() {
|
||||
const vscode = acquireVsCodeApi();
|
||||
|
||||
$(document).ready(() => {
|
||||
addPropertiesAndBehaviorsForMainToken();
|
||||
|
||||
vscode.postMessage({ command: 'documentReady'});
|
||||
});
|
||||
|
||||
function addPropertiesAndBehaviorsForMainToken() {
|
||||
const htmlQuestionsOfSubTokens = getHtmlPropertiesAndBehaviorsForToken();
|
||||
|
||||
$('#mainPropertiesAndBehaviorsToken')[0].innerHTML += htmlQuestionsOfSubTokens;
|
||||
}
|
||||
|
||||
$('#yesAddCustomDetails').click(yesNoAddCustomDetails);
|
||||
$('#noAddCustomDetails').click(yesNoAddCustomDetails);
|
||||
|
||||
$('#singleOrSolitary').click(showOrHideAdditionalOptionsForTokenType);
|
||||
$('#compositeOrHybrid').click(showOrHideAdditionalOptionsForTokenType);
|
||||
|
||||
$('#numberOfSubTokens').change(addPropertiesAndBehaviorsForSubToken);
|
||||
|
||||
$('#generateButton').click(generateToken);
|
||||
|
||||
function generateToken() {
|
||||
if (!validateTokenForm()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const tokenData = getTokenData();
|
||||
const tokenExpression = generateTokenExpression(tokenData);
|
||||
|
||||
vscode.postMessage({ command: 'tokenExpression', value: JSON.stringify(tokenExpression)});
|
||||
}
|
||||
|
||||
function getTokenData() {
|
||||
const mainPropertiesAndBehaviors = getPropertiesAndBehaviorsForToken('#mainPropertiesAndBehaviorsToken');
|
||||
const propertiesAndBehaviorsSubTokens = getPropertiesAndBehaviorsForSubTokens();
|
||||
|
||||
const additionalBehaviorsData = $('input[name=otherBehaviors]:checked').val() === 'true'
|
||||
? $('input[id=customBehaviors]').val()
|
||||
: null;
|
||||
|
||||
const customMetaData = $('input[name=addCustomDetails]:checked').val() === 'true'
|
||||
? $('input[id=customDetails]').val()
|
||||
: null;
|
||||
|
||||
return {
|
||||
additionalBehaviorsData,
|
||||
behaviors: mainPropertiesAndBehaviors,
|
||||
composite: $('input[name=tokenType]:checked').val() === 'true',
|
||||
customMetaData,
|
||||
name: $('#tokenName')[0].value,
|
||||
subTokens: propertiesAndBehaviorsSubTokens,
|
||||
};
|
||||
}
|
||||
|
||||
function isAllRequiredFieldsFilled() {
|
||||
const tokenName = $('#tokenName')[0].value;
|
||||
let isValid = true;
|
||||
|
||||
if (!tokenName) {
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
const selectedTokenType = $('input[name=tokenType]:checked');
|
||||
|
||||
if(!selectedTokenType.length) {
|
||||
$('#tokenType')[0].className = 'notificationForRequiredFields';
|
||||
isValid = false;
|
||||
} else {
|
||||
$('#tokenType')[0].className = '';
|
||||
}
|
||||
|
||||
const isComposite = selectedTokenType.val() === 'true';
|
||||
if (isComposite) {
|
||||
const elementWrapperForSubTokens = '.propertiesAndBehaviorsSubToken';
|
||||
const countOfSubTokens = $(elementWrapperForSubTokens).length;
|
||||
|
||||
for (let i = 1; i <= countOfSubTokens; i++) {
|
||||
const isSelectedAllBehaviors = checkSelectedAllBehaviors(elementWrapperForSubTokens, i);
|
||||
if (!isSelectedAllBehaviors) {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const elementWrapperForToken = '#mainPropertiesAndBehaviorsToken';
|
||||
const isSelectedAllBehaviors = checkSelectedAllBehaviors(elementWrapperForToken);
|
||||
|
||||
if (!isSelectedAllBehaviors) {
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
const isValidCustomDetails = checkCustomBehaviorsAndDetails('addCustomDetails', 'customDetails');
|
||||
|
||||
return isValid && isValidCustomDetails;
|
||||
}
|
||||
|
||||
function checkSelectedAllBehaviors(elementWrapper, id = '') {
|
||||
const numberOfBehaviors = $(`${elementWrapper} input`).length / 2;
|
||||
const numberOfSelectedBehaviors = $(`${elementWrapper} input:checked`).length;
|
||||
|
||||
addNotificationForToken(elementWrapper, id);
|
||||
|
||||
return numberOfSelectedBehaviors !== numberOfBehaviors ? false : true;
|
||||
}
|
||||
|
||||
function addNotificationForToken(elementWrapper, id) {
|
||||
$(`${elementWrapper} input[name=baseTokenType${id}]`).parent().parent()[0].className =
|
||||
$(`${elementWrapper} input[name=baseTokenType${id}]:checked`).length
|
||||
? ''
|
||||
: 'notificationForRequiredFields';
|
||||
|
||||
$(`${elementWrapper} input[name=additionalTokens${id}]`).parent().parent()[0].className =
|
||||
$(`${elementWrapper} input[name=additionalTokens${id}]:checked`).length
|
||||
? ''
|
||||
: 'notificationForRequiredFields';
|
||||
|
||||
$(`${elementWrapper} input[name=destroyTokens${id}]`).parent().parent()[0].className =
|
||||
$(`${elementWrapper} input[name=destroyTokens${id}]:checked`).length
|
||||
? ''
|
||||
: 'notificationForRequiredFields';
|
||||
|
||||
$(`${elementWrapper} input[name=transferOwnershipTokens${id}]`).parent().parent()[0].className =
|
||||
$(`${elementWrapper} input[name=transferOwnershipTokens${id}]:checked`).length
|
||||
? ''
|
||||
: 'notificationForRequiredFields';
|
||||
|
||||
$(`${elementWrapper} input[name=delegateInteractions${id}]`).parent().parent()[0].className =
|
||||
$(`${elementWrapper} input[name=delegateInteractions${id}]:checked`).length
|
||||
? ''
|
||||
: 'notificationForRequiredFields';
|
||||
}
|
||||
|
||||
function checkCustomBehaviorsAndDetails(typeCustomProperty, typeDetails) {
|
||||
const selectedCustomProperty = $(`input[name=${typeCustomProperty}]:checked`);
|
||||
if(selectedCustomProperty.length) {
|
||||
$('#addCustomDetails')[0].className = '';
|
||||
const isYes = selectedCustomProperty.val() === 'true';
|
||||
|
||||
if (isYes && !$(`input#${typeDetails}`).val()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$('#addCustomDetails')[0].className = 'notificationForRequiredFields';
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getPropertiesAndBehaviorsForToken(elementWrapper, id = '') {
|
||||
const isFungible = $(`${elementWrapper} input[name=baseTokenType${id}]:checked`).val();
|
||||
const isMintable = $(`${elementWrapper} input[name=additionalTokens${id}]:checked`).val();
|
||||
const isBurnable = $(`${elementWrapper} input[name=destroyTokens${id}]:checked`).val();
|
||||
const isTransferable = $(`${elementWrapper} input[name=transferOwnershipTokens${id}]:checked`).val();
|
||||
const isDelegate = $(`${elementWrapper} input[name=delegateInteractions${id}]:checked`).val();
|
||||
|
||||
return {
|
||||
fungible: isFungible === 'true',
|
||||
mintable: isMintable === 'true',
|
||||
burnable: isBurnable === 'true',
|
||||
transferable: isTransferable === 'true',
|
||||
delegable: isDelegate === 'true',
|
||||
};
|
||||
}
|
||||
|
||||
function getPropertiesAndBehaviorsForSubTokens() {
|
||||
let subTokensBehaviorsArray = [];
|
||||
const elementWrapper = '.propertiesAndBehaviorsSubToken';
|
||||
const countOfSubTokens = $(elementWrapper).length;
|
||||
|
||||
for (let i = 1; i <= countOfSubTokens; i++) {
|
||||
subTokensBehaviorsArray.push(getPropertiesAndBehaviorsForToken(elementWrapper, i));
|
||||
}
|
||||
|
||||
return subTokensBehaviorsArray;
|
||||
}
|
||||
|
||||
function generateTokenExpression(tokenData) {
|
||||
let template = getTokenString(tokenData.behaviors);
|
||||
|
||||
if (tokenData.customMetaData !== null) {
|
||||
const customMetaData = tokenData.customMetaData.split(',').map(x => 'str' + x.trim()).join('+');
|
||||
template = '[' + template.trim() + '+' + customMetaData + ']';
|
||||
}
|
||||
|
||||
const subTokens = tokenData.subTokens;
|
||||
if (subTokens && subTokens.length > 0) {
|
||||
template = template.concat('(');
|
||||
template = template.concat(subTokens.map(subToken => getTokenString(subToken)).join(','));
|
||||
template = template.concat(')');
|
||||
}
|
||||
|
||||
return `{"TokenName":"${tokenData.name}","Template":"${template}"}`;
|
||||
}
|
||||
|
||||
function getTokenString(behaviors) {
|
||||
const behaviorStrings = [];
|
||||
let template = '';
|
||||
|
||||
template = behaviors.fungible ? template.concat('tF{') : template.concat('tN{');
|
||||
|
||||
behaviorStrings.push(behaviors.mintable ? 'm' : '~m');
|
||||
behaviorStrings.push(behaviors.burnable ? 'b' : '~b');
|
||||
behaviorStrings.push(behaviors.transferable ? 't' : '~t');
|
||||
|
||||
if (behaviors.delegable) {
|
||||
behaviorStrings.push('g');
|
||||
}
|
||||
|
||||
template = template.concat(behaviorStrings.join(',')).concat('}');
|
||||
return template;
|
||||
}
|
||||
|
||||
function yesNoAddCustomDetails() {
|
||||
const isYes = $('#yesAddCustomDetails')[0];
|
||||
|
||||
if (isYes.checked) {
|
||||
$('#customDetails')[0].style.display = 'block';
|
||||
} else {
|
||||
$('#customDetails')[0].style.display = 'none';
|
||||
$('#customDetailsValidationTip')[0].style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function showOrHideAdditionalOptionsForTokenType() {
|
||||
const isCompositeOrHybrid = $('#compositeOrHybrid')[0];
|
||||
|
||||
if (isCompositeOrHybrid.checked) {
|
||||
$('#selectionOfSubTokens')[0].style.display = 'block';
|
||||
addPropertiesAndBehaviorsForSubToken();
|
||||
} else {
|
||||
$('#selectionOfSubTokens')[0].style.display = 'none';
|
||||
removePropertiesAndBehaviorsForSubToken();
|
||||
}
|
||||
}
|
||||
|
||||
function addPropertiesAndBehaviorsForSubToken() {
|
||||
let htmlOfPropertiesAndBehaviorsSubTokens = '';
|
||||
const numbersOfSubTokens = $('#numberOfSubTokens')[0].value;
|
||||
|
||||
for(let i = 1; i <= numbersOfSubTokens; i++) {
|
||||
|
||||
htmlOfPropertiesAndBehaviorsSubTokens +=
|
||||
'<div class="propertiesAndBehaviorsSubToken" style="margin: 20px 0 20px 0;">' +
|
||||
'<label>Please choose properties and behaviors for your sub token #' + i + '</label>' +
|
||||
getHtmlPropertiesAndBehaviorsForToken(i) +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
$('#propertiesAndBehaviorsSubTokens')[0].innerHTML = htmlOfPropertiesAndBehaviorsSubTokens;
|
||||
}
|
||||
|
||||
function removePropertiesAndBehaviorsForSubToken() {
|
||||
$('#propertiesAndBehaviorsSubTokens')[0].innerHTML = '';
|
||||
}
|
||||
|
||||
function validateCustomDetails() {
|
||||
const isAddCustomDetailsSelected = $('input[name=addCustomDetails]:checked').val() === 'true';
|
||||
const value = $('#customDetails')[0].value;
|
||||
let isValid = true;
|
||||
|
||||
if (isAddCustomDetailsSelected) {
|
||||
if (value) {
|
||||
value.split(',').forEach(item => {
|
||||
if (!isSymbols(item)) {
|
||||
isValid = false;
|
||||
}
|
||||
});
|
||||
|
||||
isValid
|
||||
? $('#customDetailsValidationTip')[0].style.display = 'none'
|
||||
: $('#customDetailsValidationTip')[0].style.display = 'block';
|
||||
return isValid;
|
||||
}
|
||||
|
||||
$('#customDetailsValidationTip')[0].style.display = 'block'
|
||||
return !isValid;
|
||||
}
|
||||
|
||||
$('#customDetailsValidationTip')[0].style.display = 'none';
|
||||
return isValid;
|
||||
}
|
||||
|
||||
function getHtmlPropertiesAndBehaviorsForToken(index = '') {
|
||||
return `<div class="paragraph">
|
||||
<div class="paragraph">
|
||||
<label>Please indicate the base type for your token.</label><br>
|
||||
<div>
|
||||
<label><input type="radio" name="baseTokenType${index}" value="true">My tokens have interchangable value (fungible)</label>
|
||||
<label><input type="radio" name="baseTokenType${index}" value="false">Every token is unique (non-fungible)</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<label>Can you create additional tokens?</label><br>
|
||||
<div>
|
||||
<label><input type="radio" name="additionalTokens${index}" value="true">Yes(Mint)</label>
|
||||
<label><input type="radio" name="additionalTokens${index}" value="false">No</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<label>Can you destroy tokens?</label><br>
|
||||
<div>
|
||||
<label><input type="radio" name="destroyTokens${index}" value="true">Yes(Burn)</label>
|
||||
<label><input type="radio" name="destroyTokens${index}" value="false">No</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<label>Can you transfer ownership of the tokens?</label><br>
|
||||
<div>
|
||||
<label><input type="radio" name="transferOwnershipTokens${index}" value="true">Yes(Transferable)</label>
|
||||
<label><input type="radio" name="transferOwnershipTokens${index}" value="false">No</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<label>Can you delegate interactions with the token to others?</label><br>
|
||||
<div>
|
||||
<label><input type="radio" class="delegateInteractions" name="delegateInteractions${index}" value="true">Yes(Delegate)</label>
|
||||
<label><input type="radio" class="delegateInteractions" name="delegateInteractions${index}" value="false">No</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function isAlphaNumeric(str) {
|
||||
var exp = /^[0-9a-zA-Z]{1,255}$/g;
|
||||
return str && str.match(exp);
|
||||
}
|
||||
|
||||
function isSymbols(str) {
|
||||
var exp = /^[a-zA-Z]+$/g;
|
||||
return str && str.match(exp);
|
||||
}
|
||||
|
||||
function validateTokenName() {
|
||||
const value = $('#tokenName').val();
|
||||
if (!value) {
|
||||
$('#tokenNameValidationTip')[0].style.display = 'block';
|
||||
return false;
|
||||
}
|
||||
|
||||
const flag = isAlphaNumeric(value);
|
||||
flag
|
||||
? $('#tokenNameValidationTip')[0].style.display = 'none'
|
||||
: $('#tokenNameValidationTip')[0].style.display = 'block';
|
||||
return flag;
|
||||
}
|
||||
|
||||
function validateTokenForm() {
|
||||
const isValidTokenName = validateTokenName();
|
||||
const isValidCustomDetails = validateCustomDetails();
|
||||
const isRequiredFieldsFilled = isAllRequiredFieldsFilled();
|
||||
|
||||
return isValidTokenName && isValidCustomDetails && isRequiredFieldsFilled;
|
||||
}
|
||||
}
|
|
@ -120,7 +120,7 @@
|
|||
<a href="https://openzeppelin.com/">
|
||||
<div class="specific-partner">
|
||||
<div><img class="small-image-logo" src="{{root}}/images/OpenZLogo.png"></div>
|
||||
<div>Open Zeppelin</div>
|
||||
<div>OpenZeppelin</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -38,6 +38,12 @@ export class Constants {
|
|||
treeManager: 'Service Tree Manager',
|
||||
};
|
||||
|
||||
public static truffleConfigRequireNames = {
|
||||
fs: 'fs',
|
||||
fsPackageName: 'fs',
|
||||
hdwalletProvider: 'HDWalletProvider',
|
||||
};
|
||||
|
||||
public static defaultTruffleBox = 'Azure-Samples/Blockchain-Ethereum-Template';
|
||||
public static defaultDebounceTimeout = 300;
|
||||
|
||||
|
@ -65,8 +71,8 @@ export class Constants {
|
|||
},
|
||||
[RequiredApps.git]: '2.10.0',
|
||||
[RequiredApps.hdwalletProvider]: {
|
||||
max: '1.0.7',
|
||||
min: '1.0.6',
|
||||
max: '2.0.0',
|
||||
min: '1.0.17',
|
||||
},
|
||||
[RequiredApps.node]: '10.15.0',
|
||||
[RequiredApps.npm]: '6.4.1',
|
||||
|
@ -109,6 +115,12 @@ export class Constants {
|
|||
title: 'Smart Contract UI',
|
||||
viewType: 'contractUIPage',
|
||||
},
|
||||
generateToken: {
|
||||
path: '',
|
||||
showOnStartup: 'showOnStartupGenerateToken',
|
||||
title: 'Generate Token',
|
||||
viewType: 'generateTokenPage',
|
||||
},
|
||||
requirements: {
|
||||
path: '',
|
||||
showOnStartup: 'showOnStartupRequirementsPage',
|
||||
|
@ -138,6 +150,7 @@ export class Constants {
|
|||
public static contractProperties = {
|
||||
abi: 'abi',
|
||||
bytecode: 'bytecode',
|
||||
deployedBytecode: 'deployedBytecode',
|
||||
};
|
||||
|
||||
public static propertyLabels = {
|
||||
|
@ -449,16 +462,20 @@ export class Constants {
|
|||
consortiumNameValidating: 'Consortium name validating...',
|
||||
contractNotDeployed: 'Contract not deployed yet.',
|
||||
deployButton: 'Deploy',
|
||||
deployFailed: 'Deploy failed',
|
||||
deploySucceeded: 'Deploy succeeded',
|
||||
detailsButton: 'Details',
|
||||
generatedLogicApp: 'Generated the logic app!',
|
||||
infuraAccountSuccessfullyCreated: 'Your Infura account successfully created. Please check you email for complete registration',
|
||||
infuraSignInPrompt: 'Not signed in to Infura account, sign in first.',
|
||||
installButton: 'Install',
|
||||
invalidRequiredVersion: 'Required app is not installed or has an old version.',
|
||||
memberNameValidating: 'Member name validating...',
|
||||
newProjectCreationFinished: 'New project was created successfully',
|
||||
newProjectCreationStarted: 'New project creation is started',
|
||||
openButton: 'Open',
|
||||
privateKeyWasCopiedToClipboard: 'Private key was copied to clipboard',
|
||||
requiresDependency: 'This project deployment requires the truffle-hdwallet-provider.',
|
||||
rpcEndpointCopiedToClipboard: 'RPCEndpointAddress copied to clipboard',
|
||||
seeDetailsRequirementsPage: 'Please see details on the Requirements Page',
|
||||
signInButton: 'Sign In',
|
||||
|
@ -574,6 +591,8 @@ export class Constants {
|
|||
this.webViewPages.contractUI.path = context.asAbsolutePath(path.join('resources', 'drizzle', 'index.html'));
|
||||
this.webViewPages.welcome.path = context.asAbsolutePath(path.join('resources', 'welcome', 'index.html'));
|
||||
this.webViewPages.requirements.path = context.asAbsolutePath(path.join('resources', 'welcome', 'prereqs.html'));
|
||||
this.webViewPages.generateToken.path = context.asAbsolutePath(
|
||||
path.join('resources', 'tokenui', 'generateToken.html'));
|
||||
this.infuraFileResponse.path = context.asAbsolutePath(path.join('resources', 'codeFlowResult', 'index.html'));
|
||||
this.infuraFileResponse.css = context.asAbsolutePath(path.join('resources', 'codeFlowResult', 'main.css'));
|
||||
|
||||
|
|
|
@ -2657,7 +2657,7 @@ $d.define(Nethereum.Generators.DataWorkflow.LogicApps.DataWorkflowFunctionOutput
|
|||
return null;
|
||||
};
|
||||
$p.GetConnectionSection = function DataWorkflowFunctionOutputLogicAppTemplate_GetConnectionSection(subsciptionId) {
|
||||
return String.Format(" \"$connections\": {{\r\n \"value\": {{\r\n \"blockchainethereum\": {{\r\n \"connectionId\": \"/subscriptions/{0}/resourceGroups/\",\r\n \"connectionName\": \"\",\r\n \"id\": \"/subscriptions/{1}/providers/Microsoft.Web/locations/{2}/managedApis/blockchainethereum\"\r\n }},\r\n \"sql\": {{\r\n \"connectionId\": \"/subscriptions/{3}/resourceGroups/\",\r\n \"connectionName\": \"\",\r\n \"id\": \"/subscriptions/{4}/providers/Microsoft.Web/locations/{5}/managedApis/sql\"\r\n }}\r\n }}\r\n }},",
|
||||
return String.Format(" \"parameters\": {{\r\n \"$connections\": {{\r\n \"value\": {{\r\n \"blockchainethereum\": {{\r\n \"connectionId\": \"/subscriptions/{0}/resourceGroups/\",\r\n \"connectionName\": \"\",\r\n \"id\": \"/subscriptions/{1}/providers/Microsoft.Web/locations/{2}/managedApis/blockchainethereum\"\r\n }},\r\n \"sql\": {{\r\n \"connectionId\": \"/subscriptions/{3}/resourceGroups/\",\r\n \"connectionName\": \"\",\r\n \"id\": \"/subscriptions/{4}/providers/Microsoft.Web/locations/{5}/managedApis/sql\"\r\n }}\r\n }}\r\n }}\r\n }},",
|
||||
[subsciptionId, subsciptionId, this._location, subsciptionId, subsciptionId, this._location]);
|
||||
};
|
||||
$p.GetLogicAppStart = function DataWorkflowFunctionOutputLogicAppTemplate_GetLogicAppStart() {
|
||||
|
@ -3552,7 +3552,7 @@ $d.define(Nethereum.Generators.MessagingWorkflow.LogicApps.MessagingWorkflowEven
|
|||
return null;
|
||||
};
|
||||
$p.GetConnectionSection = function MessagingWorkflowEventLogicAppTemplate_GetConnectionSection(subscriptionId) {
|
||||
return String.Format(" \"$connections\": {{\r\n \"value\": {{\r\n \"blockchainethereum\": {{\r\n \"connectionId\": \"/subscriptions/{0}/resourceGroups/\",\r\n \"connectionName\": \"\",\r\n \"id\": \"/subscriptions/{1}/providers/Microsoft.Web/locations/{2}/managedApis/blockchainethereum\"\r\n }},\r\n {3}\r\n }}\r\n }},",
|
||||
return String.Format(" \"parameters\": {{\r\n \"$connections\": {{\r\n \"value\": {{\r\n \"blockchainethereum\": {{\r\n \"connectionId\": \"/subscriptions/{0}/resourceGroups/\",\r\n \"connectionName\": \"\",\r\n \"id\": \"/subscriptions/{1}/providers/Microsoft.Web/locations/{2}/managedApis/blockchainethereum\"\r\n }},\r\n {3}\r\n }}\r\n }}\r\n }},",
|
||||
[subscriptionId, subscriptionId, this._location, this.GetConnection(subscriptionId)]);
|
||||
};
|
||||
$p.GetConnection = function MessagingWorkflowEventLogicAppTemplate_GetConnection(subscriptionId) {
|
||||
|
@ -3594,10 +3594,12 @@ $d.define(Nethereum.Generators.MessagingWorkflow.LogicApps.MessagingWorkflowEven
|
|||
var beginActions = String.Format("\"actions\": {{\r\n \"Publish_Event\": {{\r\n \"inputs\": {{\r\n \"body\": [\r\n {{\r\n \"data\": \"@triggerBody()\",\r\n \"eventTime\": \"@{{utcNow()}}\",\r\n \"eventType\": \"{0}\",\r\n \"id\": \"@{{guid()}}\",\r\n \"subject\": \"{1}\"\r\n }}\r\n ]",
|
||||
[this.get_Model().get_EventABI().get_Name(), this._topicName]);
|
||||
|
||||
var paths = "/eventGrid/api/events";
|
||||
var eventProperties = String.Concat(System.Linq.Enumerable.Select(Nethereum.Generators.Model.ParameterABI,
|
||||
String, this.get_Model().get_EventABI().get_InputParameters(), $d.delegate(function(p) {
|
||||
return "'\\\"" + p.get_Name() + "\\\": ',triggerBody()?['" + p.get_Name() + "'],',','\\n',";
|
||||
})));
|
||||
|
||||
var endActions = String.Format(",\r\n \"host\": {{\r\n \"connection\": {{\r\n \"name\": \"@parameters('$connections')['azureeventgridpublish']['connectionId']\"\r\n }}\r\n }},\r\n \"method\": \"post\",\r\n \"path\": \"{0}\"\r\n }},\r\n \"runAfter\": {{}},\r\n \"type\": \"ApiConnection\"\r\n }}\r\n }}",
|
||||
[paths]);
|
||||
var endActions = ",\r\n \"host\": {\r\n \"connection\": {\r\n \"name\": \"@parameters('$connections')['azureeventgridpublish']['connectionId']\"\r\n }\r\n },\r\n \"method\": \"post\",\r\n \"path\": \"/eventGrid/api/events\"\r\n },\r\n \"runAfter\": {},\r\n \"type\": \"ApiConnection\"\r\n }\r\n }";
|
||||
return String.Concat$5(beginActions, endActions);
|
||||
};
|
||||
$p.GetServiceBusActions = function MessagingWorkflowEventLogicAppTemplate_GetServiceBusActions() {
|
||||
|
@ -4073,7 +4075,7 @@ $d.define(Nethereum.Generators.ReportingWorkflow.LogicApps.ReportingWorkflowEven
|
|||
return null;
|
||||
};
|
||||
$p.GetConnectionSection = function ReportingWorkflowEventsOutputLogicAppTemplate_GetConnectionSection(subsciptionId) {
|
||||
return String.Format(" \"$connections\": {{\r\n \"value\": {{\r\n \"blockchainethereum\": {{\r\n \"connectionId\": \"/subscriptions/{0}/resourceGroups/\",\r\n \"connectionName\": \"\",\r\n \"id\": \"/subscriptions/{1}/providers/Microsoft.Web/locations/{2}/managedApis/blockchainethereum\"\r\n }},\r\n \"powerbi\": {{\r\n \"connectionId\": \"/subscriptions/{3}/resourceGroups/\",\r\n \"connectionName\": \"\",\r\n \"id\": \"/subscriptions/{4}/providers/Microsoft.Web/locations/{5}/managedApis/powerbi\"\r\n }}\r\n }}\r\n }},",
|
||||
return String.Format(" \"parameters\": {{\r\n \"$connections\": {{\r\n \"value\": {{\r\n \"blockchainethereum\": {{\r\n \"connectionId\": \"/subscriptions/{0}/resourceGroups/\",\r\n \"connectionName\": \"\",\r\n \"id\": \"/subscriptions/{1}/providers/Microsoft.Web/locations/{2}/managedApis/blockchainethereum\"\r\n }},\r\n \"powerbi\": {{\r\n \"connectionId\": \"/subscriptions/{3}/resourceGroups/\",\r\n \"connectionName\": \"\",\r\n \"id\": \"/subscriptions/{4}/providers/Microsoft.Web/locations/{5}/managedApis/powerbi\"\r\n }}\r\n }}\r\n }}\r\n }},",
|
||||
[subsciptionId, subsciptionId, this._location, subsciptionId, subsciptionId, this._location]);
|
||||
};
|
||||
$p.GetLogicAppStart = function ReportingWorkflowEventsOutputLogicAppTemplate_GetLogicAppStart() {
|
||||
|
@ -5040,7 +5042,7 @@ $d.define(Nethereum.Generators.ServiceWorkflow.FlowApps.ServiceWorkflowFunctionO
|
|||
|
||||
};
|
||||
$p.GetExecuteFunctionActionForLogicApp = function ServiceWorkflowFunctionOutputFlowAppTemplate_GetExecuteFunctionActionForLogicApp() {
|
||||
return " \"actions\": {\r\n \"Call smart contract function\": {\r\n \"runAfter\": { },\r\n \"type\": \"ApiConnection\",\r\n \"inputs\": {\r\n \"body\": {\r\n" + this.GetEthereumConnectorParameters() + "\r\n },\r\n \"host\": {\r\n \"connection\": {\r\n \"name\": \"@parameters('$connections')['shared_blockchainethereum']['connectionId']\"\r\n }\r\n },\r\n \"method\": \"post\",\r\n \"path\": \"/contract/functions/@{encodeURIComponent(encodeURIComponent('" + this.get_Model().get_FunctionABI().get_Name() + "'))}/" + (this.get_Model().get_FunctionABI().get_Constant() ? "query" : "execute") + "\",\r\n \"queries\": {\r\n \"abi\": \"" + this._escapedAbi + "\",\r\n\r\n \"contractAddress\": \"" + this._contractAddress + "\"\r\n }\r\n }\r\n },";
|
||||
return " \"actions\": {\r\n \"Call smart contract function\": {\r\n \"runAfter\": { },\r\n \"type\": \"ApiConnection\",\r\n \"inputs\": {\r\n \"body\": {\r\n" + this.GetEthereumConnectorParameters() + "\r\n },\r\n \"host\": { \"parameters\": {{\r\n \"connection\": {\r\n \"name\": \"@parameters('$connections')['shared_blockchainethereum']['connectionId']\"\r\n }\r\n }\r\n },\r\n \"method\": \"post\",\r\n \"path\": \"/contract/functions/@{encodeURIComponent(encodeURIComponent('" + this.get_Model().get_FunctionABI().get_Name() + "'))}/" + (this.get_Model().get_FunctionABI().get_Constant() ? "query" : "execute") + "\",\r\n \"queries\": {\r\n \"abi\": \"" + this._escapedAbi + "\",\r\n\r\n \"contractAddress\": \"" + this._contractAddress + "\"\r\n }\r\n }\r\n },";
|
||||
};
|
||||
$p.GetEthereumConnectorParameters = function ServiceWorkflowFunctionOutputFlowAppTemplate_GetEthereumConnectorParameters() {
|
||||
return String.Join$1(String, ",\r\n", System.Linq.Enumerable.Select(Nethereum.Generators.Model.ParameterABI,
|
||||
|
@ -5436,7 +5438,7 @@ $d.define(Nethereum.Generators.ServiceWorkflow.LogicApps.ServiceWorkflowFunction
|
|||
return null;
|
||||
};
|
||||
$p.GetConnections = function ServiceWorkflowFunctionOutputLogicAppTemplate_GetConnections() {
|
||||
return String.Format("{{ \"$connections\": {{\r\n \"value\": {{\r\n \"blockchainethereum\": {{\r\n \"connectionId\": \"/subscriptions/{0}/resourceGroups/\",\r\n \"connectionName\": \"\",\r\n \"id\": \"/subscriptions/{1}/providers/Microsoft.Web/locations/{2}/managedApis/blockchainethereum\"\r\n }}\r\n }}\r\n }},",
|
||||
return String.Format("{{ \"parameters\": {{\r\n \"$connections\": {{\r\n \"value\": {{\r\n \"blockchainethereum\": {{\r\n \"connectionId\": \"/subscriptions/{0}/resourceGroups/\",\r\n \"connectionName\": \"\",\r\n \"id\": \"/subscriptions/{1}/providers/Microsoft.Web/locations/{2}/managedApis/blockchainethereum\"\r\n }}\r\n }}\r\n }}\r\n }},",
|
||||
[this._subsciptionId, this._subsciptionId, this._location]);
|
||||
};
|
||||
$p.GetLogicAppStart = function ServiceWorkflowFunctionOutputLogicAppTemplate_GetLogicAppStart() {
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { Constants } from '../../Constants';
|
||||
import { Constants, RequiredApps } from '../../Constants';
|
||||
import { saveTextInFile, showInputBox, showQuickPick, TruffleConfiguration } from '../../helpers';
|
||||
import { MnemonicRepository } from '../../services/MnemonicRepository'; // Should be full path since cycle dependencies
|
||||
import { NetworkNode } from './NetworkNode';
|
||||
|
@ -14,7 +14,9 @@ export abstract class MnemonicNetworkNode extends NetworkNode {
|
|||
const targetURL = await this.getRPCAddress();
|
||||
const mnemonic = await this.getMnemonic();
|
||||
|
||||
await config.importPackage('fs', 'fs');
|
||||
const { fs, fsPackageName, hdwalletProvider } = Constants.truffleConfigRequireNames;
|
||||
await config.importPackage(fs, fsPackageName);
|
||||
await config.importPackage(hdwalletProvider, RequiredApps.hdwalletProvider);
|
||||
|
||||
network.options.provider = {
|
||||
mnemonic: mnemonic.path,
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import { commands, ExtensionContext, Uri, window } from 'vscode';
|
||||
import { Constants } from '../Constants';
|
||||
import { CancellationEvent } from '../Models';
|
||||
import { GenerateToken } from '../pages';
|
||||
import { ContractUI } from '../pages/ContractUI';
|
||||
import { ContractDB, ContractService } from '../services';
|
||||
import { Telemetry } from '../TelemetryClient';
|
||||
|
@ -47,4 +48,13 @@ export namespace ContractCommands {
|
|||
await contractPage.show();
|
||||
Telemetry.sendEvent('ContractCommands.showSmartContract.commandFinished');
|
||||
}
|
||||
|
||||
export async function generateToken(context: ExtensionContext): Promise<void> {
|
||||
Telemetry.sendEvent('ContractCommands.generateToken.commandStarted');
|
||||
|
||||
const contractPage = new GenerateToken(context);
|
||||
|
||||
await contractPage.show();
|
||||
Telemetry.sendEvent('ContractCommands.generateToken.commandFinished');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,15 +26,15 @@ export namespace OpenZeppelinCommands {
|
|||
Constants.outputChannel.azureBlockchain,
|
||||
Constants.openZeppelin.categoryWillDownloaded(category.name),
|
||||
);
|
||||
const assetStatuses = OpenZeppelinService.getAssetsStatus(fullAssetWithDependencies);
|
||||
const assetsStatuses = OpenZeppelinService.getAssetsStatus(fullAssetWithDependencies);
|
||||
Output.outputLine(
|
||||
Constants.outputChannel.azureBlockchain,
|
||||
Constants.openZeppelin.fileNow(assetStatuses.existing.length),
|
||||
Constants.openZeppelin.fileNow(assetsStatuses.existing.length),
|
||||
);
|
||||
|
||||
if (assetStatuses.existing.length > 0) {
|
||||
if (assetsStatuses.existing.length > 0) {
|
||||
const answer = await window.showInformationMessage(
|
||||
Constants.openZeppelin.alreadyExisted(assetStatuses.existing),
|
||||
Constants.openZeppelin.alreadyExisted(assetsStatuses.existing),
|
||||
Constants.openZeppelin.replaceButtonTitle,
|
||||
Constants.openZeppelin.skipButtonTitle,
|
||||
);
|
||||
|
@ -47,7 +47,7 @@ export namespace OpenZeppelinCommands {
|
|||
);
|
||||
await downloadFileSetWithProgress(fullAssetWithDependencies, true);
|
||||
} else {
|
||||
await downloadFileSetWithProgress(assetStatuses.missing, false);
|
||||
await downloadFileSetWithProgress(assetsStatuses.missing, false);
|
||||
}
|
||||
} else {
|
||||
await downloadFileSetWithProgress(fullAssetWithDependencies, false);
|
||||
|
@ -119,13 +119,17 @@ async function selectCategory(categories: IOZContractCategory[]): Promise<IOZCon
|
|||
}
|
||||
|
||||
async function openDocumentationUrl(category: IOZContractCategory): Promise<void> {
|
||||
const documentationUrl = OpenZeppelinService.getCategoryApiDocumentationUrl(category);
|
||||
if (!documentationUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
const answer = await window.showInformationMessage(
|
||||
Constants.openZeppelin.exploreDownloadedContractsInfo,
|
||||
Constants.openZeppelin.moreDetailsButtonTitle,
|
||||
Constants.openZeppelin.cancelButtonTitle);
|
||||
|
||||
if (answer === Constants.openZeppelin.moreDetailsButtonTitle) {
|
||||
const documentationUrl = OpenZeppelinService.getCategoryApiDocumentationUrl(category);
|
||||
open(documentationUrl);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import {
|
|||
TruffleConfiguration,
|
||||
} from '../helpers';
|
||||
import { CancellationEvent } from '../Models';
|
||||
import { Output } from '../Output';
|
||||
import { Telemetry } from '../TelemetryClient';
|
||||
|
||||
interface IProjectDestination {
|
||||
|
@ -96,7 +95,6 @@ async function createProjectFromTruffleBox(projectPath: string): Promise<void> {
|
|||
|
||||
async function createProject(projectPath: string, truffleBoxName: string): Promise<void> {
|
||||
try {
|
||||
Output.show();
|
||||
Telemetry.sendEvent('ProjectCommands.createProject.unbox', { truffleBoxName });
|
||||
await outputCommandHelper.executeCommand(projectPath, 'npx', RequiredApps.truffle, 'unbox', truffleBoxName);
|
||||
|
||||
|
|
|
@ -56,7 +56,6 @@ export namespace TruffleCommands {
|
|||
await required.installTruffle(required.Scope.locally);
|
||||
}
|
||||
|
||||
Output.show();
|
||||
await outputCommandHelper.executeCommand(getWorkspaceRoot(), 'npx', RequiredApps.truffle, 'compile');
|
||||
});
|
||||
Telemetry.sendEvent('TruffleCommands.buildContracts.commandFinished');
|
||||
|
@ -90,18 +89,6 @@ export namespace TruffleCommands {
|
|||
{ url: Telemetry.obfuscate(command.description || '') },
|
||||
);
|
||||
|
||||
// this code should be below showQuickPick because it takes time and it affects on responsiveness
|
||||
if (!await required.checkAppsSilent(RequiredApps.truffle)) {
|
||||
Telemetry.sendEvent('TruffleCommands.deployContracts.installTruffle');
|
||||
await required.installTruffle(required.Scope.locally);
|
||||
}
|
||||
|
||||
if (await required.isHdWalletProviderRequired()
|
||||
&& !(await required.checkHdWalletProviderVersion())) {
|
||||
Telemetry.sendEvent('TruffleCommands.deployContracts.installTruffleHdWalletProvider');
|
||||
await required.installTruffleHdWalletProvider();
|
||||
}
|
||||
|
||||
await validateOpenZeppelinContracts();
|
||||
|
||||
await command.cmd();
|
||||
|
@ -125,6 +112,14 @@ export namespace TruffleCommands {
|
|||
Telemetry.sendEvent('TruffleCommands.writeBytecodeToBuffer.commandFinished');
|
||||
}
|
||||
|
||||
export async function writeDeployedBytecodeToBuffer(uri: Uri): Promise<void> {
|
||||
Telemetry.sendEvent('TruffleCommands.writeBytecodeToBuffer.commandStarted');
|
||||
const contract = await readCompiledContract(uri);
|
||||
|
||||
await vscodeEnvironment.writeToClipboard(contract[Constants.contractProperties.deployedBytecode]);
|
||||
Telemetry.sendEvent('TruffleCommands.writeBytecodeToBuffer.commandFinished');
|
||||
}
|
||||
|
||||
export async function writeRPCEndpointAddressToBuffer(projectView: ProjectView): Promise<void> {
|
||||
Telemetry.sendEvent('TruffleCommands.writeRPCEndpointAddressToBuffer.commandStarted');
|
||||
const rpcEndpointAddress = await projectView.extensionItem.getRPCAddress();
|
||||
|
@ -190,6 +185,28 @@ function removeDuplicateNetworks(deployDestinations: IDeployDestinationItem[]):
|
|||
});
|
||||
}
|
||||
|
||||
async function installRequiredDependencies(): Promise<void> {
|
||||
if (!await required.checkAppsSilent(RequiredApps.truffle)) {
|
||||
Telemetry.sendEvent('TruffleCommands.installRequiredDependencies.installTruffle');
|
||||
await required.installTruffle(required.Scope.locally);
|
||||
}
|
||||
|
||||
if (await required.isHdWalletProviderRequired() && !(await required.checkHdWalletProviderVersion())) {
|
||||
|
||||
if (!await required.isDefaultProject()) {
|
||||
const { cancelButton, installButton, requiresDependency } = Constants.informationMessage;
|
||||
const answer = await window.showInformationMessage(requiresDependency, installButton, cancelButton);
|
||||
|
||||
if (answer !== installButton) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Telemetry.sendEvent('TruffleCommands.installRequiredDependencies.installTruffleHdWalletProvider');
|
||||
await required.installTruffleHdWalletProvider();
|
||||
}
|
||||
}
|
||||
|
||||
async function validateOpenZeppelinContracts(): Promise<void> {
|
||||
const validatedContracts = await OpenZeppelinService.validateContracts();
|
||||
validatedContracts.forEach((ozContract: OZContractValidated) => {
|
||||
|
@ -386,11 +403,19 @@ async function deployToNetwork(networkName: string, truffleConfigPath: string):
|
|||
const workspaceRoot = path.dirname(truffleConfigPath);
|
||||
|
||||
await fs.ensureDir(workspaceRoot);
|
||||
await outputCommandHelper.executeCommand(
|
||||
workspaceRoot,
|
||||
'npx',
|
||||
RequiredApps.truffle, 'migrate', '--reset', '--network', networkName,
|
||||
);
|
||||
|
||||
try {
|
||||
await installRequiredDependencies();
|
||||
await outputCommandHelper.executeCommand(
|
||||
workspaceRoot,
|
||||
'npx',
|
||||
RequiredApps.truffle, 'migrate', '--reset', '--network', networkName,
|
||||
);
|
||||
Output.outputLine(Constants.outputChannel.azureBlockchain, Constants.informationMessage.deploySucceeded);
|
||||
} catch (error) {
|
||||
Output.outputLine(Constants.outputChannel.azureBlockchain, Constants.informationMessage.deployFailed);
|
||||
throw error;
|
||||
}
|
||||
|
||||
await ContractDB.updateContracts();
|
||||
});
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import * as truffleDebugUtils from '@truffle/debug-utils';
|
||||
import * as truffleDebugger from '@truffle/debugger';
|
||||
import { EventEmitter } from 'events';
|
||||
import { relative as pathRelative } from 'path';
|
||||
import * as truffleDebugUtils from 'truffle-debug-utils';
|
||||
import * as truffleDebugger from 'truffle-debugger';
|
||||
import {
|
||||
filterContractsWithAddress,
|
||||
prepareContracts,
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
declare module '@truffle/debug-utils' {
|
||||
function nativize(variables: any): any;
|
||||
|
||||
export { nativize };
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
declare module '@truffle/debugger' {
|
||||
interface Selectors {
|
||||
solidity: any,
|
||||
evm: any,
|
||||
controller: any,
|
||||
trace: any,
|
||||
}
|
||||
const selectors: Selectors;
|
||||
|
||||
interface Session {
|
||||
removeAllBreakpoints: () => Promise<void>,
|
||||
view: (selectors: any) => any,
|
||||
addBreakpoint: (breakPoint: any) => {},
|
||||
variables: () => Promise<any>,
|
||||
continueUntilBreakpoint: () => Promise<void>,
|
||||
stepNext: () => Promise<void>,
|
||||
stepInto: () => Promise<void>,
|
||||
stepOut: () => Promise<void>,
|
||||
}
|
||||
|
||||
interface Debugger {
|
||||
connect: () => Session,
|
||||
}
|
||||
|
||||
function forTx(txHash: string, debugOptions: any): Promise<Debugger>;
|
||||
|
||||
export { selectors, Selectors, forTx, Session };
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
declare module '@truffle/provider' {
|
||||
interface IProviderOptions {
|
||||
provider?: any,
|
||||
host?: string,
|
||||
port?: number,
|
||||
websockets?: boolean,
|
||||
}
|
||||
function create(networkOptions: IProviderOptions): any;
|
||||
export { create };
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
import * as truffleProvider from 'truffle-provider';
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import * as truffleProvider from '@truffle/provider';
|
||||
import * as web3 from 'web3';
|
||||
import { ConfigurationReader } from './configurationReader';
|
||||
|
||||
|
|
|
@ -87,6 +87,9 @@ export async function activate(context: ExtensionContext) {
|
|||
const copyByteCode = commands.registerCommand('contract.copyByteCode', async (uri: Uri) => {
|
||||
await tryExecute(() => TruffleCommands.writeBytecodeToBuffer(uri));
|
||||
});
|
||||
const copyDeployedByteCode = commands.registerCommand('contract.copyDeployedByteCode', async (uri: Uri) => {
|
||||
await tryExecute(() => TruffleCommands.writeDeployedBytecodeToBuffer(uri));
|
||||
});
|
||||
const copyABI = commands.registerCommand('contract.copyABI', async (uri: Uri) => {
|
||||
await tryExecute(() => TruffleCommands.writeAbiToBuffer(uri));
|
||||
});
|
||||
|
@ -132,6 +135,11 @@ export async function activate(context: ExtensionContext) {
|
|||
async (contractPath: Uri) => {
|
||||
await tryExecute(() => ContractCommands.showSmartContractPage(context, contractPath));
|
||||
});
|
||||
const generateToken = commands.registerCommand(
|
||||
'azureBlockchainService.generateToken',
|
||||
async () => {
|
||||
await tryExecute(() => ContractCommands.generateToken(context));
|
||||
});
|
||||
//#endregion
|
||||
|
||||
//#region open zeppelin commands
|
||||
|
@ -173,6 +181,7 @@ export async function activate(context: ExtensionContext) {
|
|||
showWelcomePage,
|
||||
showRequirementsPage,
|
||||
showSmartContractPage,
|
||||
generateToken,
|
||||
refresh,
|
||||
newSolidityProject,
|
||||
buildContracts,
|
||||
|
@ -181,6 +190,7 @@ export async function activate(context: ExtensionContext) {
|
|||
connectProject,
|
||||
disconnectProject,
|
||||
copyByteCode,
|
||||
copyDeployedByteCode,
|
||||
copyABI,
|
||||
copyRPCEndpointAddress,
|
||||
startGanacheServer,
|
||||
|
|
|
@ -37,7 +37,6 @@ export async function executeCommand(workingDirectory: string | undefined, comma
|
|||
);
|
||||
|
||||
if (result.code !== 0) {
|
||||
Output.show();
|
||||
Telemetry.sendException(new Error('commands.executeCommand.resultWithIncorrectCode'));
|
||||
throw new Error(Constants.executeCommandMessage.failedToRunCommand(commands.concat(' ', ...args.join(' '))));
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import * as fs from 'fs-extra';
|
||||
import * as path from 'path';
|
||||
import * as semver from 'semver';
|
||||
import { commands, window } from 'vscode';
|
||||
import { commands, ProgressLocation, window } from 'vscode';
|
||||
import { Constants, RequiredApps } from '../Constants';
|
||||
import { Output } from '../Output';
|
||||
import { Telemetry } from '../TelemetryClient';
|
||||
|
@ -252,22 +252,32 @@ export namespace required {
|
|||
);
|
||||
const truffleConfigPath = await TruffleConfiguration.getTruffleConfigUri();
|
||||
const config = new TruffleConfiguration.TruffleConfig(truffleConfigPath);
|
||||
await config.importPackage('HDWalletProvider', RequiredApps.hdwalletProvider);
|
||||
await config.importPackage(Constants.truffleConfigRequireNames.hdwalletProvider, RequiredApps.hdwalletProvider);
|
||||
} catch (error) {
|
||||
Telemetry.sendException(error);
|
||||
}
|
||||
}
|
||||
|
||||
export async function isHdWalletProviderRequired(): Promise<boolean> {
|
||||
try {
|
||||
const truffleConfigPath = TruffleConfiguration.getTruffleConfigUri();
|
||||
const config = new TruffleConfiguration.TruffleConfig(truffleConfigPath);
|
||||
return config.isHdWalletProviderDeclared();
|
||||
} catch (error) {
|
||||
Telemetry.sendException(error);
|
||||
Output.outputLine(Constants.outputChannel.requirements, error.message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export async function isDefaultProject(): Promise<boolean> {
|
||||
try {
|
||||
// File might not exist in some truffle-box
|
||||
const data = await fs.readFile(path.join(getWorkspaceRoot()!, 'package.json'), 'utf-8');
|
||||
const packagesData = JSON.parse(data);
|
||||
if (packagesData.name === 'blockchain-ethereum-template') {
|
||||
const truffleConfigPath = TruffleConfiguration.getTruffleConfigUri();
|
||||
const config = new TruffleConfiguration.TruffleConfig(truffleConfigPath);
|
||||
return config.isHdWalletProviderDeclared();
|
||||
}
|
||||
|
||||
return packagesData.name === 'blockchain-ethereum-template';
|
||||
} catch (error) {
|
||||
Telemetry.sendException(error);
|
||||
Output.outputLine(Constants.outputChannel.requirements, error.message);
|
||||
|
@ -299,8 +309,6 @@ export namespace required {
|
|||
packageVersion: string | { min: string, max: string },
|
||||
scope?: Scope,
|
||||
): Promise<void> {
|
||||
Output.show();
|
||||
|
||||
const versionString = typeof packageVersion === 'string' ?
|
||||
`^${packageVersion}` :
|
||||
`>=${packageVersion.min} <${packageVersion.max}`;
|
||||
|
@ -313,7 +321,12 @@ export namespace required {
|
|||
throw error;
|
||||
}
|
||||
|
||||
await executeCommand(workspaceRoot, 'npm', 'i', scope ? '' : '-g', ` ${packageName}@"${versionString}"`);
|
||||
await window.withProgress({
|
||||
location: ProgressLocation.Window,
|
||||
title: `Installing ${packageName}`,
|
||||
}, async () => {
|
||||
await executeCommand(workspaceRoot, 'npm', 'i', scope ? '' : '-g', ` ${packageName}@"${versionString}"`);
|
||||
});
|
||||
}
|
||||
|
||||
async function getVersion(program: string, command: string, matcher: RegExp): Promise<string> {
|
||||
|
|
|
@ -11,6 +11,7 @@ import * as ESTree from 'estree';
|
|||
import * as fs from 'fs-extra';
|
||||
import * as path from 'path';
|
||||
import { Constants } from '../Constants';
|
||||
import { MnemonicRepository } from '../services';
|
||||
import { Telemetry } from '../TelemetryClient';
|
||||
import { getWorkspaceRoot } from './workspace';
|
||||
|
||||
|
@ -246,12 +247,18 @@ export namespace TruffleConfiguration {
|
|||
}
|
||||
|
||||
function isHdWalletProviderDeclaration(nodeType: string, node: ESTree.Node): boolean {
|
||||
if (nodeType !== 'NewExpression') {
|
||||
return false;
|
||||
if (nodeType === 'NewExpression') {
|
||||
node = node as ESTree.NewExpression;
|
||||
node = node.callee as ESTree.Identifier;
|
||||
return node.name === Constants.truffleConfigRequireNames.hdwalletProvider;
|
||||
}
|
||||
node = node as ESTree.NewExpression;
|
||||
node = node.callee as ESTree.Identifier;
|
||||
return node.name === 'HDWalletProvider';
|
||||
|
||||
if (nodeType === 'VariablePattern') {
|
||||
node = node as ESTree.Identifier;
|
||||
return node.name === Constants.truffleConfigRequireNames.hdwalletProvider;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getModuleExportsObjectExpression(ast: ESTree.Node): ESTree.ObjectExpression | void {
|
||||
|
@ -301,7 +308,8 @@ export namespace TruffleConfiguration {
|
|||
function isHDWalletProvider(nodeType: string, node: ESTree.Node): boolean {
|
||||
if (nodeType === 'NewExpression') {
|
||||
node = node as ESTree.NewExpression;
|
||||
if (node.callee.type === 'Identifier' && node.callee.name === 'HDWalletProvider') {
|
||||
if (node.callee.type === 'Identifier'
|
||||
&& node.callee.name === Constants.truffleConfigRequireNames.hdwalletProvider) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -448,14 +456,22 @@ export namespace TruffleConfiguration {
|
|||
return obj;
|
||||
}
|
||||
|
||||
function isMnemonicNode(node: ESTree.Literal | ESTree.NewExpression): boolean {
|
||||
return node && node.type === 'Literal' && typeof node.value === 'string';
|
||||
}
|
||||
|
||||
function astToHDWalletProvider(node: ESTree.NewExpression): IProvider {
|
||||
const provider: IProvider = {
|
||||
raw: generate(node),
|
||||
};
|
||||
|
||||
const mnemonicNode = node.arguments[0];
|
||||
if (mnemonicNode && mnemonicNode.type === 'Literal') {
|
||||
provider.mnemonic = '' + mnemonicNode.value;
|
||||
const mnemonicNode = node.arguments[0] as ESTree.NewExpression & ESTree.Literal;
|
||||
const mnemonicFilePathNode = mnemonicNode && mnemonicNode.arguments && mnemonicNode.arguments[0] as ESTree.Literal;
|
||||
|
||||
if (isMnemonicNode(mnemonicNode)) {
|
||||
provider.mnemonic = mnemonicNode.value as string;
|
||||
} else if (isMnemonicNode(mnemonicFilePathNode)) {
|
||||
provider.mnemonic = MnemonicRepository.getMnemonic(mnemonicFilePathNode.value as string);
|
||||
}
|
||||
|
||||
const urlNode = node.arguments[1];
|
||||
|
@ -477,7 +493,7 @@ export namespace TruffleConfiguration {
|
|||
generateLiteral(provider.url || ''),
|
||||
],
|
||||
callee: {
|
||||
name: 'HDWalletProvider',
|
||||
name: Constants.truffleConfigRequireNames.hdwalletProvider,
|
||||
type: 'Identifier',
|
||||
},
|
||||
type: 'NewExpression',
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { ExtensionContext } from 'vscode';
|
||||
import { Constants } from '../Constants';
|
||||
import { BasicWebView, IWebViewConfig } from './BasicWebView';
|
||||
|
||||
export class GenerateToken extends BasicWebView {
|
||||
protected readonly config: IWebViewConfig;
|
||||
|
||||
constructor(context: ExtensionContext) {
|
||||
super(context);
|
||||
this.config = Object.assign({}, Constants.webViewPages.generateToken);
|
||||
}
|
||||
|
||||
protected async setShowOnStartupFlagAtFirstTime(): Promise<boolean> {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected async receiveMessage(message: {[key: string]: any}): Promise<void> {
|
||||
await super.receiveMessage(message);
|
||||
|
||||
if (!this.panel) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.command === 'tokenExpression') {
|
||||
// TODO: change this to process tokenExpression
|
||||
// @ts-ignore
|
||||
const tokenExpression = message.value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { GenerateToken } from './GenerateToken';
|
||||
import { RequirementsPage } from './Requirements';
|
||||
import { WelcomePage } from './Welcome';
|
||||
|
||||
export {
|
||||
GenerateToken,
|
||||
RequirementsPage,
|
||||
WelcomePage,
|
||||
};
|
||||
|
|
|
@ -3,14 +3,10 @@
|
|||
|
||||
import * as requestPromise from 'request-promise';
|
||||
import { Constants } from '../Constants';
|
||||
import { Output } from '../Output';
|
||||
import { Telemetry } from '../TelemetryClient';
|
||||
|
||||
export namespace HttpService {
|
||||
export async function sendRPCRequest(
|
||||
host: string,
|
||||
methodName: string,
|
||||
): Promise<{ result?: any } | undefined> {
|
||||
export async function sendRPCRequest(host: string, methodName: string): Promise<{ result?: any } | undefined> {
|
||||
const address = hasProtocol(host) ? host : `${Constants.networkProtocols.http}${host}`;
|
||||
return requestPromise.post(
|
||||
address,
|
||||
|
@ -23,15 +19,7 @@ export namespace HttpService {
|
|||
},
|
||||
json: true,
|
||||
})
|
||||
.then((result) => {
|
||||
const message = `HttpService.sendRPCRequest has done with result: ${result}`;
|
||||
Output.outputLine(Constants.outputChannel.azureBlockchain, message);
|
||||
|
||||
return result;
|
||||
})
|
||||
.catch((errorMessage) => {
|
||||
const message = `HttpService.sendRPCRequest has done with error: ${errorMessage}`;
|
||||
Output.outputLine(Constants.outputChannel.azureBlockchain, message);
|
||||
.catch((_errorMessage) => {
|
||||
Telemetry.sendException(new Error(`HttpService.sendRPCRequest has done with error for method: ${methodName}`));
|
||||
|
||||
return undefined;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as fs from 'fs';
|
||||
import * as fs from 'fs-extra';
|
||||
import { Memento } from 'vscode';
|
||||
import { Constants } from '../Constants';
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ export namespace NetworkService {
|
|||
|
||||
return {
|
||||
network: { id: networkId || '*', name: truffleNetwork.name },
|
||||
provider: host ? { host } : null,
|
||||
provider: host ? { host, options: { mnemonic: options.provider && options.provider.mnemonic } } : null,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ export interface ProviderOptions {
|
|||
timeout?: number;
|
||||
headers?: HttpHeader[];
|
||||
withCredentials?: boolean;
|
||||
mnemonic?: string;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line:interface-name
|
||||
|
|
|
@ -92,7 +92,6 @@ export namespace GanacheService {
|
|||
addAllListeners(output, port, process);
|
||||
await waitGanacheStarted(port, Constants.ganacheRetryAttempts);
|
||||
ganacheProcess.pid = await findPid(port);
|
||||
output.show();
|
||||
} catch (error) {
|
||||
Telemetry.sendException(error);
|
||||
await stopGanacheProcess(ganacheProcess, true);
|
||||
|
|
|
@ -28,7 +28,7 @@ export namespace OpenZeppelinMigrationsService {
|
|||
'};',
|
||||
].join('\n');
|
||||
|
||||
saveMigrationContent(migrationContent);
|
||||
return saveMigrationContent(migrationContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,16 +62,17 @@ function generateLibrariesDeployerSection(items: IOZAsset[]): string {
|
|||
|
||||
async function generateLinkingSection(items: IOZAsset[]): Promise<string[]> {
|
||||
const librariesLinkingSection: string[] = [];
|
||||
items
|
||||
.filter((asset: IOZAsset) => asset.type === OZAssetType.contract)
|
||||
.forEach(async (asset: IOZAsset) => {
|
||||
librariesLinkingSection.push(
|
||||
...contractToLibraryLinkingSection(
|
||||
asset,
|
||||
await OpenZeppelinService.getReferencesToLibraries(asset),
|
||||
),
|
||||
);
|
||||
});
|
||||
const contracts = items.filter((asset) => asset.type === OZAssetType.contract);
|
||||
|
||||
for (const contract of contracts) {
|
||||
librariesLinkingSection.push(
|
||||
...contractToLibraryLinkingSection(
|
||||
contract,
|
||||
await OpenZeppelinService.getReferencesToLibraries(contract),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return librariesLinkingSection;
|
||||
}
|
||||
|
||||
|
@ -88,16 +89,16 @@ async function saveMigrationContent(content: string): Promise<void> {
|
|||
const truffleConfig = new TruffleConfiguration.TruffleConfig(truffleConfigPath);
|
||||
const configuration = truffleConfig.getConfiguration();
|
||||
const migrationFilePath = configuration.migrations_directory;
|
||||
const filePath = path.join(
|
||||
getWorkspaceRoot()!,
|
||||
migrationFilePath,
|
||||
migrationFilename,
|
||||
);
|
||||
|
||||
Output.outputLine(
|
||||
Constants.outputChannel.azureBlockchain,
|
||||
`New migration for OpenZeppelin contracts was stored to file ${migrationFilename}`,
|
||||
);
|
||||
|
||||
const filePath = path.join(
|
||||
getWorkspaceRoot()!,
|
||||
migrationFilePath,
|
||||
migrationFilename,
|
||||
);
|
||||
fs.writeFileSync(filePath, content, { encoding: 'utf8' });
|
||||
return fs.writeFile(filePath, content, { encoding: 'utf8' });
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import * as _metadata from './manifest.json';
|
|||
|
||||
const metadata = _metadata as IOZMetadata;
|
||||
const projectFileName: string = 'project.json';
|
||||
const categoryWithoutDocumentation = 'mocks';
|
||||
|
||||
export interface IOZMetadata {
|
||||
contentVersion: string;
|
||||
|
@ -98,8 +99,8 @@ export namespace OpenZeppelinService {
|
|||
return result;
|
||||
}
|
||||
|
||||
contractDependencies.dependencies.forEach(async (id: string) => {
|
||||
const dependency = metadata.assets.find((asset: IOZAsset) => asset.id === id)!;
|
||||
for (const dependencyId of contractDependencies.dependencies) {
|
||||
const dependency = metadata.assets.find((asset: IOZAsset) => asset.id === dependencyId)!;
|
||||
if (dependency.type === OZAssetType.library) {
|
||||
if (!result.includes(dependency)) {
|
||||
result.push(dependency);
|
||||
|
@ -111,7 +112,7 @@ export namespace OpenZeppelinService {
|
|||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -145,19 +146,23 @@ export namespace OpenZeppelinService {
|
|||
|
||||
export function getAssetsStatus(assets: IOZAsset[]): { existing: IOZAsset[], missing: IOZAsset[] } {
|
||||
const openZeppelinSubfolder = getContractFolderPath();
|
||||
const statuses = assets.map((asset) => {
|
||||
if (fs.existsSync(path.join(openZeppelinSubfolder, path.dirname(asset.name)))) {
|
||||
return {asset, exists: true};
|
||||
}
|
||||
return {asset, exists: false};
|
||||
const assetsStatuses = assets.map((asset) => {
|
||||
const assetPath = getAssetFullPath(openZeppelinSubfolder, asset);
|
||||
|
||||
return { asset, exists: fs.existsSync(assetPath) };
|
||||
});
|
||||
|
||||
return {
|
||||
existing: statuses.filter((status) => status.exists === true).map((status) => status.asset),
|
||||
missing: statuses.filter((status) => status.exists === false).map((status) => status.asset),
|
||||
existing: assetsStatuses.filter((status) => status.exists === true).map((status) => status.asset),
|
||||
missing: assetsStatuses.filter((status) => status.exists === false).map((status) => status.asset),
|
||||
};
|
||||
}
|
||||
|
||||
export function getCategoryApiDocumentationUrl(category: IOZContractCategory) {
|
||||
if (category.id === categoryWithoutDocumentation) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const baseUrl = appendSlashIfNotExists(metadata.apiDocumentationBaseUri);
|
||||
return url.resolve(baseUrl, category.id);
|
||||
}
|
||||
|
@ -216,23 +221,23 @@ function isFileExists(filePath: string) {
|
|||
|
||||
async function downloadFile(asset: IOZAsset, overwrite: boolean = false, openZeppelinSubfolder: string)
|
||||
: Promise<IDownloadingResult> {
|
||||
const fileUrl = new URL(path.join(metadata.targetPoint, asset.name), metadata.baseUri).toString();
|
||||
const destinationPath = path.join(openZeppelinSubfolder, path.dirname(asset.name));
|
||||
const destinationFile = path.join(destinationPath, path.basename(asset.name));
|
||||
const fileUrl = new URL(getAssetFullPath(metadata.targetPoint, asset), metadata.baseUri).toString();
|
||||
const destinationFilePath = getAssetFullPath(openZeppelinSubfolder, asset);
|
||||
const destinationDirPath = path.dirname(destinationFilePath);
|
||||
|
||||
if (fs.existsSync(destinationFile)) {
|
||||
if (fs.existsSync(destinationFilePath)) {
|
||||
if (overwrite) {
|
||||
await fs.chmod(destinationFile, 0o222); // reset r/o flag, this allows to overwrite
|
||||
await fs.chmod(destinationFilePath, 0o222); // reset r/o flag, this allows to overwrite
|
||||
} else {
|
||||
Output.outputLine(Constants.outputChannel.azureBlockchain, `${fileUrl} - Skipped`);
|
||||
return { state: PromiseState.fileExisted, asset };
|
||||
}
|
||||
}
|
||||
|
||||
return download(fileUrl, destinationPath, { filename: path.basename(asset.name) })
|
||||
return download(fileUrl, destinationDirPath, { filename: path.basename(destinationFilePath) })
|
||||
.then(async () => {
|
||||
Output.outputLine(Constants.outputChannel.azureBlockchain, `${fileUrl} - OK`);
|
||||
await fs.chmod(destinationFile, 0o444);
|
||||
await fs.chmod(destinationFilePath, 0o444);
|
||||
return { state: PromiseState.fulfilled, asset };
|
||||
})
|
||||
.catch(() => {
|
||||
|
@ -258,8 +263,7 @@ function getOzContractsFromProjectMetadata(
|
|||
openZeppelinSubfolder: string,
|
||||
userProjectMetadata: IProjectMetadata) {
|
||||
return Object.values(userProjectMetadata.openZeppelin.assets)
|
||||
// map assetName to contractPath
|
||||
.map((asset) => path.join(openZeppelinSubfolder, asset.name));
|
||||
.map((asset) => getAssetFullPath(openZeppelinSubfolder, asset));
|
||||
}
|
||||
|
||||
function getOriginalHash(
|
||||
|
@ -273,3 +277,7 @@ function getOriginalHash(
|
|||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function getAssetFullPath(baseDir: string, asset: IOZAsset) {
|
||||
return path.join(baseDir, asset.name);
|
||||
}
|
||||
|
|
|
@ -478,7 +478,7 @@ describe('AzureBlockchainServiceClient', () => {
|
|||
pipelineMock.restore();
|
||||
});
|
||||
|
||||
function assertRequestFailed(error: any, callbackFunctionSpy: sinon.SinonSpy): void {
|
||||
function assertRequestFailed(error: any, callbackFunctionSpy: sinon.SinonSpy<[Error | null, any?], void>): void {
|
||||
assert.strictEqual(pipelineMock.calledOnce, true, 'pipeline should called once');
|
||||
assert.strictEqual(
|
||||
showErrorMessageMock.calledOnceWithExactly(error.message),
|
||||
|
@ -490,7 +490,10 @@ describe('AzureBlockchainServiceClient', () => {
|
|||
'callbackFunction should called once with correct arguments');
|
||||
}
|
||||
|
||||
function assertResponseNotSuccess(callbackFunctionSpy: sinon.SinonSpy, pipelineCallbackSpy: sinon.SinonSpy): void {
|
||||
function assertResponseNotSuccess(
|
||||
callbackFunctionSpy: sinon.SinonSpy<[Error | null, any?], void>,
|
||||
pipelineCallbackSpy: sinon.SinonSpy)
|
||||
: void {
|
||||
assert.strictEqual(pipelineMock.calledOnce, true, 'pipeline should called once');
|
||||
assert.strictEqual(showErrorMessageMock.notCalled, true, 'showErrorMessage should not called');
|
||||
assert.strictEqual(callbackFunctionSpy.calledOnce, true, 'callbackFunction should called once');
|
||||
|
@ -506,7 +509,7 @@ describe('AzureBlockchainServiceClient', () => {
|
|||
}
|
||||
|
||||
function assertResponseSuccess(
|
||||
callbackFunctionSpy: sinon.SinonSpy,
|
||||
callbackFunctionSpy: sinon.SinonSpy<[Error | null, any?], void>,
|
||||
pipelineCallbackSpy: sinon.SinonSpy,
|
||||
parsedResult: any)
|
||||
: void {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as fs from 'fs';
|
||||
import * as fs from 'fs-extra';
|
||||
import * as os from 'os';
|
||||
import * as sinon from 'sinon';
|
||||
import uuid = require('uuid');
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import * as assert from 'assert';
|
||||
import * as sinon from 'sinon';
|
||||
import * as uuid from 'uuid';
|
||||
import { window } from 'vscode';
|
||||
import { CancellationToken, Progress, ProgressOptions, window } from 'vscode';
|
||||
import { TruffleCommands } from '../../src/commands/TruffleCommands';
|
||||
import * as helpers from '../../src/helpers';
|
||||
import * as commands from '../../src/helpers/command';
|
||||
|
@ -18,7 +18,8 @@ describe('BuildContracts Command', () => {
|
|||
let installTruffle: sinon.SinonExpectation;
|
||||
let commandContextMock: sinon.SinonMock;
|
||||
let executeCommandMock: sinon.SinonExpectation;
|
||||
let withProgressStub: sinon.SinonStub<any[], any>;
|
||||
let withProgressStub: sinon.SinonStub<[
|
||||
ProgressOptions, (progress: Progress<any>, token: CancellationToken) => any], any>;
|
||||
|
||||
beforeEach(() => {
|
||||
requiredMock = sinon.mock(helpers.required);
|
||||
|
|
|
@ -48,11 +48,12 @@ describe('TruffleCommands', () => {
|
|||
let showQuickPickMock: any;
|
||||
let showInputBoxMock: any;
|
||||
let showSaveDialogMock: sinon.SinonExpectation;
|
||||
let showInformationMessageMock: any;
|
||||
|
||||
let ganacheServiceMock: sinon.SinonMock;
|
||||
let startGanacheServerMock: sinon.SinonExpectation;
|
||||
|
||||
let getItemsMock: sinon.SinonStub<[(boolean | undefined)?], IExtensionItem[]>;
|
||||
let getItemsMock: sinon.SinonStub<[], IExtensionItem[]>;
|
||||
let loadStateMock: sinon.SinonStub<[], IExtensionItem[]>;
|
||||
let servicesItems: Service[];
|
||||
|
||||
|
@ -93,7 +94,7 @@ describe('TruffleCommands', () => {
|
|||
showInputBoxMock = sinon.stub(vscode.window, 'showInputBox');
|
||||
showSaveDialogMock = windowMock.expects('showSaveDialog');
|
||||
sinon.stub(vscode.window, 'showErrorMessage');
|
||||
sinon.stub(vscode.window, 'showInformationMessage');
|
||||
showInformationMessageMock = sinon.stub(vscode.window, 'showInformationMessage');
|
||||
|
||||
ganacheServiceMock = sinon.mock(GanacheService);
|
||||
startGanacheServerMock = ganacheServiceMock.expects('startGanacheServer');
|
||||
|
@ -159,7 +160,9 @@ describe('TruffleCommands', () => {
|
|||
checkAppsSilentMock.returns(true);
|
||||
getWorkspaceRootMock.returns(path.join(__dirname, TestConstants.truffleCommandTestDataFolder));
|
||||
isHdWalletProviderRequiredMock.returns(true);
|
||||
checkHdWalletProviderVersionMock.returns(false);
|
||||
executeCommandMock.returns(uuid.v4());
|
||||
showInformationMessageMock.returns(Constants.informationMessage.installButton);
|
||||
|
||||
showQuickPickMock.onCall(0).callsFake((items: any) => {
|
||||
return items.find((item: any) => item.label === TestConstants.servicesNames.development);
|
||||
|
@ -231,6 +234,7 @@ describe('TruffleCommands', () => {
|
|||
checkAppsSilentMock.returns(true);
|
||||
getWorkspaceRootMock.returns(path.join(__dirname, TestConstants.truffleCommandTestDataFolder));
|
||||
executeCommandMock.returns(uuid.v4());
|
||||
isHdWalletProviderRequiredMock.returns(false);
|
||||
|
||||
showQuickPickMock.onCall(0).callsFake((items: any) => {
|
||||
return items.find((item: any) => item.label === TestConstants.servicesNames.development);
|
||||
|
|
|
@ -22,7 +22,7 @@ import { ProjectView } from '../../src/ViewItems';
|
|||
|
||||
describe('Integration tests GanacheCommands', () => {
|
||||
const defaultPort = 8545;
|
||||
let getItemsMock: sinon.SinonStub<[(boolean | undefined)?], IExtensionItem[]>;
|
||||
let getItemsMock: sinon.SinonStub<[], IExtensionItem[]>;
|
||||
let serviceItems: Service[];
|
||||
let loadStateMock: sinon.SinonStub<[], IExtensionItem[]>;
|
||||
let projectView: ProjectView;
|
||||
|
|
|
@ -26,7 +26,7 @@ import { TestConstants } from '../TestConstants';
|
|||
describe('Unit tests GanacheCommands', () => {
|
||||
let checkAppsStub: sinon.SinonStub<RequiredApps[], Promise<boolean>>;
|
||||
|
||||
let getItemsMock: sinon.SinonStub<[(boolean | undefined)?], IExtensionItem[]>;
|
||||
let getItemsMock: sinon.SinonStub<[], IExtensionItem[]>;
|
||||
let testServiceItems: Service[];
|
||||
let loadStateMock: sinon.SinonStub<[], IExtensionItem[]>;
|
||||
let projectView: ProjectView;
|
||||
|
|
|
@ -6,7 +6,16 @@ import * as path from 'path';
|
|||
import rewire = require('rewire');
|
||||
import * as sinon from 'sinon';
|
||||
import uuid = require('uuid');
|
||||
import { window } from 'vscode';
|
||||
import {
|
||||
CancellationToken,
|
||||
MessageItem,
|
||||
MessageOptions,
|
||||
Progress,
|
||||
ProgressOptions,
|
||||
QuickPickItem,
|
||||
QuickPickOptions,
|
||||
window,
|
||||
} from 'vscode';
|
||||
import { Constants } from '../../src/Constants';
|
||||
import { TruffleConfiguration } from '../../src/helpers/truffleConfig';
|
||||
import * as workspace from '../../src/helpers/workspace';
|
||||
|
@ -23,18 +32,21 @@ import {
|
|||
|
||||
describe('OpenZeppelinCommands tests', () => {
|
||||
let testCategories: IOZContractCategory[];
|
||||
let getCategoriesStub: sinon.SinonStub<any[], any> | sinon.SinonStub<unknown[], unknown>;
|
||||
let collectAssetsWithDependenciesStub: sinon.SinonStub<any[], any> | sinon.SinonStub<unknown[], unknown>;
|
||||
let downloadFilesStub: sinon.SinonStub<any[], any> | sinon.SinonStub<unknown[], unknown>;
|
||||
let getCategoriesStub: sinon.SinonStub<[], IOZContractCategory[]>;
|
||||
let collectAssetsWithDependenciesStub: sinon.SinonStub<[(string[] | undefined)?], IOZAsset[]>;
|
||||
let downloadFilesStub: sinon.SinonStub<[IOZAsset[], (boolean | undefined)?], Promise<IDownloadingResult[]>>;
|
||||
let addAssetsToProjectJsonStub: sinon.SinonStub<[IOZAsset[]], Promise<void>>;
|
||||
let getAssetsStatusStub: sinon.SinonStub<any>;
|
||||
let generateMigrationsStub: sinon.SinonStub<[IOZAsset[]], Promise<void>>;
|
||||
let getCategoryApiDocumentationUrlStub: sinon.SinonStub<any>;
|
||||
|
||||
let withProgressStub: sinon.SinonStub<any[], any>;
|
||||
let showQuickPickStub: sinon.SinonStub<any[], any>;
|
||||
let showInformationMessageStub: sinon.SinonStub<any[], any>;
|
||||
let showErrorMessageStub: sinon.SinonStub<any[], any>;
|
||||
let withProgressStub: sinon.SinonStub<[ProgressOptions,
|
||||
(progress: Progress<any>, token: CancellationToken) => any], any>;
|
||||
let showQuickPickStub: sinon.SinonStub<
|
||||
[QuickPickItem[] | Thenable<QuickPickItem[]>, (QuickPickOptions | undefined)?, (CancellationToken | undefined)?],
|
||||
any>;
|
||||
let showInformationMessageStub: sinon.SinonStub<[string, MessageOptions, ...MessageItem[]], any>;
|
||||
let showErrorMessageStub: sinon.SinonStub<[string, MessageOptions, ...MessageItem[]], any>;
|
||||
|
||||
let selectedCategory: IOZContractCategory;
|
||||
let testAssets: IOZAsset[];
|
||||
|
@ -63,7 +75,8 @@ describe('OpenZeppelinCommands tests', () => {
|
|||
getAssetsStatusStub = sinon.stub(OpenZeppelinService, 'getAssetsStatus');
|
||||
downloadFilesStub = sinon.stub(OpenZeppelinService, 'downloadFiles');
|
||||
generateMigrationsStub = sinon.stub(OpenZeppelinMigrationsService, 'generateMigrations');
|
||||
getCategoryApiDocumentationUrlStub = sinon.stub(OpenZeppelinService, 'getCategoryApiDocumentationUrl');
|
||||
getCategoryApiDocumentationUrlStub = sinon.stub(OpenZeppelinService, 'getCategoryApiDocumentationUrl')
|
||||
.returns('testUrl');
|
||||
|
||||
getAssetsStatusStub.returns({ existing: [], missing: testAssets });
|
||||
|
||||
|
@ -86,7 +99,7 @@ describe('OpenZeppelinCommands tests', () => {
|
|||
state: PromiseState.fulfilled,
|
||||
});
|
||||
});
|
||||
downloadFilesStub.returns(testDownloadingResult);
|
||||
downloadFilesStub.resolves(testDownloadingResult);
|
||||
|
||||
openStub = sinon.stub().resolves();
|
||||
const openZeppelinCommandsRewire = rewire('../../src/commands/OpenZeppelinCommands');
|
||||
|
@ -227,11 +240,11 @@ describe('OpenZeppelinCommands tests', () => {
|
|||
it('should show error message if some files failed on downloading and allow to retry', async () => {
|
||||
// Arrange
|
||||
const rejectedAssets = [
|
||||
{ asset: {}, state: PromiseState.rejected },
|
||||
{ asset: {}, state: PromiseState.rejected },
|
||||
{ asset: {} as IOZAsset, state: PromiseState.rejected },
|
||||
{ asset: {} as IOZAsset, state: PromiseState.rejected },
|
||||
];
|
||||
downloadFilesStub.returns([
|
||||
{ asset: {}, state: PromiseState.fulfilled },
|
||||
downloadFilesStub.resolves([
|
||||
{ asset: {} as IOZAsset, state: PromiseState.fulfilled },
|
||||
...rejectedAssets,
|
||||
]);
|
||||
showErrorMessageStub
|
||||
|
@ -267,6 +280,22 @@ describe('OpenZeppelinCommands tests', () => {
|
|||
`open should be called with ${testDocumentationUrl}`);
|
||||
assert.strictEqual(openStub.calledAfter(downloadFilesStub), true, 'open should be called after downloadFiles');
|
||||
});
|
||||
|
||||
it('should not ask and open category documentation if it doesn\'t exist', async () => {
|
||||
// Arrange
|
||||
getCategoryApiDocumentationUrlStub.returns(undefined);
|
||||
generateMigrationsStub.resolves();
|
||||
|
||||
// Act
|
||||
await openZeppelinCommands.addCategory();
|
||||
|
||||
// Assert
|
||||
assert.strictEqual(
|
||||
showInformationMessageStub.calledWith(Constants.openZeppelin.exploreDownloadedContractsInfo),
|
||||
false,
|
||||
'showInformationMessageStub should not be called with explore contracts info message');
|
||||
assert.strictEqual(openStub.called, false, 'open should not be called');
|
||||
});
|
||||
});
|
||||
|
||||
function getTestCategories(): IOZContractCategory[] {
|
||||
|
|
|
@ -5,7 +5,7 @@ import * as assert from 'assert';
|
|||
import * as fs from 'fs-extra';
|
||||
import rewire = require('rewire');
|
||||
import * as sinon from 'sinon';
|
||||
import * as vscode from 'vscode';
|
||||
import { CancellationToken, Progress, ProgressOptions, window, workspace } from 'vscode';
|
||||
import { Constants, RequiredApps } from '../../src/Constants';
|
||||
import * as helpers from '../../src/helpers';
|
||||
import { CancellationEvent } from '../../src/Models';
|
||||
|
@ -23,7 +23,8 @@ describe('ProjectCommands', () => {
|
|||
let gitInitMock: sinon.SinonStub<any[], any>;
|
||||
let requiredMock: sinon.SinonMock;
|
||||
let checkRequiredAppsMock: sinon.SinonExpectation;
|
||||
let withProgressStub: sinon.SinonStub<any[], any>;
|
||||
let withProgressStub: sinon.SinonStub<
|
||||
[ProgressOptions, (progress: Progress<any>, token: CancellationToken) => any], any>;
|
||||
|
||||
beforeEach(() => {
|
||||
helpersMock = sinon.mock(helpers);
|
||||
|
@ -36,7 +37,7 @@ describe('ProjectCommands', () => {
|
|||
requiredMock = sinon.mock(helpers.required);
|
||||
checkRequiredAppsMock = requiredMock.expects('checkRequiredApps');
|
||||
|
||||
withProgressStub = sinon.stub(vscode.window, 'withProgress');
|
||||
withProgressStub = sinon.stub(window, 'withProgress');
|
||||
withProgressStub.callsFake(async (...args: any[]) => {
|
||||
return args[1]();
|
||||
});
|
||||
|
@ -108,7 +109,7 @@ describe('ProjectCommands', () => {
|
|||
ensureDirMock = fsMock.expects('ensureDir');
|
||||
readdirMock = fsMock.expects('readdir');
|
||||
|
||||
windowMock = sinon.mock(vscode.window);
|
||||
windowMock = sinon.mock(window);
|
||||
showErrorMessageMock = windowMock.expects('showErrorMessage');
|
||||
});
|
||||
|
||||
|
@ -204,10 +205,11 @@ describe('ProjectCommands', () => {
|
|||
});
|
||||
|
||||
describe('createNewEmptyProject', () => {
|
||||
let withProgressStub: sinon.SinonStub<any[], any>;
|
||||
let withProgressStub: sinon.SinonStub<
|
||||
[ProgressOptions, (progress: Progress<any>, token: CancellationToken) => any], any>;
|
||||
|
||||
beforeEach(() => {
|
||||
withProgressStub = sinon.stub(vscode.window, 'withProgress');
|
||||
withProgressStub = sinon.stub(window, 'withProgress');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -252,8 +254,6 @@ describe('ProjectCommands', () => {
|
|||
});
|
||||
|
||||
describe('createProject', () => {
|
||||
let outputMock: sinon.SinonMock;
|
||||
let showMock: sinon.SinonExpectation;
|
||||
let outputCommandHelperMock: sinon.SinonMock;
|
||||
let executeCommandMock: sinon.SinonExpectation;
|
||||
let workspaceMock: sinon.SinonMock;
|
||||
|
@ -262,11 +262,9 @@ describe('ProjectCommands', () => {
|
|||
let emptyDirSyncMock: sinon.SinonExpectation;
|
||||
|
||||
beforeEach(() => {
|
||||
outputMock = sinon.mock(Output);
|
||||
showMock = outputMock.expects('show');
|
||||
outputCommandHelperMock = sinon.mock(helpers.outputCommandHelper);
|
||||
executeCommandMock = outputCommandHelperMock.expects('executeCommand');
|
||||
workspaceMock = sinon.mock(vscode.workspace);
|
||||
workspaceMock = sinon.mock(workspace);
|
||||
updateWorkspaceFoldersMock = workspaceMock.expects('updateWorkspaceFolders');
|
||||
fsMock = sinon.mock(fs);
|
||||
emptyDirSyncMock = fsMock.expects('emptyDirSync');
|
||||
|
@ -279,7 +277,7 @@ describe('ProjectCommands', () => {
|
|||
it('Method createProject run command for create new project and project was created successfully. ' +
|
||||
'Workspace was updated to certain workspace.', async () => {
|
||||
// Arrange
|
||||
sinon.stub(vscode.workspace, 'workspaceFolders').value(['1']);
|
||||
sinon.stub(workspace, 'workspaceFolders').value(['1']);
|
||||
const projectCommandsRewire = rewire('../../src/commands/ProjectCommands');
|
||||
const createProject = projectCommandsRewire.__get__('createProject');
|
||||
|
||||
|
@ -287,7 +285,6 @@ describe('ProjectCommands', () => {
|
|||
await createProject(projectPath, truffleBoxName);
|
||||
|
||||
// Assert
|
||||
assert.strictEqual(showMock.calledOnce, true, 'show should be called once');
|
||||
assert.strictEqual(executeCommandMock.calledOnce, true, 'executeCommand should be called once');
|
||||
assert.strictEqual(
|
||||
executeCommandMock.args[0][0],
|
||||
|
@ -328,7 +325,7 @@ describe('ProjectCommands', () => {
|
|||
it('Method createProject run command for create new project and project was created successfully. ' +
|
||||
'Workspace was not updated to certain workspace.', async () => {
|
||||
// Arrange
|
||||
sinon.stub(vscode.workspace, 'workspaceFolders').value(undefined);
|
||||
sinon.stub(workspace, 'workspaceFolders').value(undefined);
|
||||
const projectCommandsRewire = rewire('../../src/commands/ProjectCommands');
|
||||
const createProject = projectCommandsRewire.__get__('createProject');
|
||||
|
||||
|
@ -336,7 +333,6 @@ describe('ProjectCommands', () => {
|
|||
await createProject(projectPath, truffleBoxName);
|
||||
|
||||
// Assert
|
||||
assert.strictEqual(showMock.calledOnce, true, 'show should be called once');
|
||||
assert.strictEqual(executeCommandMock.calledOnce, true, 'executeCommand should be called once');
|
||||
assert.strictEqual(
|
||||
executeCommandMock.args[0][0],
|
||||
|
@ -390,7 +386,6 @@ describe('ProjectCommands', () => {
|
|||
action,
|
||||
Error,
|
||||
Constants.errorMessageStrings.NewProjectCreationFailed);
|
||||
assert.strictEqual(showMock.calledOnce, true, 'show should be called once');
|
||||
assert.strictEqual(executeCommandMock.calledOnce, true, 'executeCommand should be called once');
|
||||
assert.strictEqual(
|
||||
executeCommandMock.args[0][0],
|
||||
|
@ -460,11 +455,11 @@ describe('ProjectCommands', () => {
|
|||
let outputCommandHelperMock: sinon.SinonMock;
|
||||
let executeCommandMock: sinon.SinonExpectation;
|
||||
let outputMock: sinon.SinonMock;
|
||||
let showMock: sinon.SinonExpectation;
|
||||
let workspaceMock: sinon.SinonMock;
|
||||
let updateWorkspaceFoldersMock: sinon.SinonExpectation;
|
||||
let emptyDirSyncMock: sinon.SinonExpectation;
|
||||
let withProgressStub: sinon.SinonStub<any[], any>;
|
||||
let withProgressStub: sinon.SinonStub<
|
||||
[ProgressOptions, (progress: Progress<any>, token: CancellationToken) => any], any>;
|
||||
|
||||
beforeEach(() => {
|
||||
helpersMock = sinon.mock(helpers);
|
||||
|
@ -486,15 +481,14 @@ describe('ProjectCommands', () => {
|
|||
readdirMock = fsMock.expects('readdir');
|
||||
emptyDirSyncMock = fsMock.expects('emptyDirSync');
|
||||
|
||||
windowMock = sinon.mock(vscode.window);
|
||||
windowMock = sinon.mock(window);
|
||||
showErrorMessageMock = windowMock.expects('showErrorMessage');
|
||||
workspaceMock = sinon.mock(vscode.workspace);
|
||||
workspaceMock = sinon.mock(workspace);
|
||||
updateWorkspaceFoldersMock = workspaceMock.expects('updateWorkspaceFolders');
|
||||
|
||||
outputMock = sinon.mock(Output);
|
||||
showMock = outputMock.expects('show');
|
||||
|
||||
withProgressStub = sinon.stub(vscode.window, 'withProgress');
|
||||
withProgressStub = sinon.stub(window, 'withProgress');
|
||||
withProgressStub.callsFake(async (...args: any[]) => {
|
||||
return args[1]();
|
||||
});
|
||||
|
@ -559,7 +553,7 @@ describe('ProjectCommands', () => {
|
|||
it('Method chooseNewProjectDir returns projectPath which we selected at first time.', async () => {
|
||||
// Arrange
|
||||
checkRequiredAppsMock.returns(true);
|
||||
sinon.stub(vscode.workspace, 'workspaceFolders').value(['1']);
|
||||
sinon.stub(workspace, 'workspaceFolders').value(['1']);
|
||||
readdirMock.returns([]);
|
||||
showQuickPickMock.returns({
|
||||
cmd: () => undefined,
|
||||
|
@ -591,7 +585,7 @@ describe('ProjectCommands', () => {
|
|||
// Arrange
|
||||
checkRequiredAppsMock.returns(true);
|
||||
readdirMock.returns([]);
|
||||
sinon.stub(vscode.workspace, 'workspaceFolders').value(['1']);
|
||||
sinon.stub(workspace, 'workspaceFolders').value(['1']);
|
||||
|
||||
const projectCommandsRewire = rewire('../../src/commands/ProjectCommands');
|
||||
const createNewEmptyProject = projectCommandsRewire.__get__('createNewEmptyProject');
|
||||
|
@ -619,7 +613,6 @@ describe('ProjectCommands', () => {
|
|||
assert.strictEqual(readdirMock.calledOnce, true, 'readdir should be called once');
|
||||
assert.strictEqual(readdirMock.args[0][0], firstProjectPath, 'readdir should be called with correct arguments');
|
||||
assert.strictEqual(showErrorMessageMock.notCalled, true, 'showErrorMessage should not be called');
|
||||
assert.strictEqual(showMock.calledOnce, true, 'show should be called once');
|
||||
assert.strictEqual(executeCommandMock.calledOnce, true, 'executeCommand should be called once');
|
||||
assert.strictEqual(
|
||||
executeCommandMock.args[0][0],
|
||||
|
@ -694,7 +687,6 @@ describe('ProjectCommands', () => {
|
|||
assert.strictEqual(readdirMock.calledOnce, true, 'readdir should be called once');
|
||||
assert.strictEqual(readdirMock.args[0][0], firstProjectPath, 'readdir should be called with correct arguments');
|
||||
assert.strictEqual(showErrorMessageMock.notCalled, true, 'showErrorMessage should not be called');
|
||||
assert.strictEqual(showMock.calledOnce, true, 'show should be called once');
|
||||
assert.strictEqual(executeCommandMock.calledOnce, true, 'executeCommand should be called once');
|
||||
assert.strictEqual(
|
||||
executeCommandMock.args[0][0],
|
||||
|
@ -729,7 +721,7 @@ describe('ProjectCommands', () => {
|
|||
// Arrange
|
||||
checkRequiredAppsMock.returns(true);
|
||||
readdirMock.returns([]);
|
||||
sinon.stub(vscode.workspace, 'workspaceFolders').value(['1']);
|
||||
sinon.stub(workspace, 'workspaceFolders').value(['1']);
|
||||
|
||||
const projectCommandsRewire = rewire('../../src/commands/ProjectCommands');
|
||||
projectCommandsRewire.__set__('getTruffleBoxName', sinon.mock().returns(truffleBoxName));
|
||||
|
@ -760,7 +752,6 @@ describe('ProjectCommands', () => {
|
|||
assert.strictEqual(readdirMock.calledOnce, true, 'readdir should be called once');
|
||||
assert.strictEqual(readdirMock.args[0][0], firstProjectPath, 'readdir should be called with correct arguments');
|
||||
assert.strictEqual(showErrorMessageMock.notCalled, true, 'showErrorMessage should not be called');
|
||||
assert.strictEqual(showMock.calledOnce, true, 'show should be called once');
|
||||
assert.strictEqual(executeCommandMock.calledOnce, true, 'executeCommand should be called once');
|
||||
assert.strictEqual(
|
||||
executeCommandMock.args[0][0],
|
||||
|
@ -838,7 +829,6 @@ describe('ProjectCommands', () => {
|
|||
assert.strictEqual(readdirMock.calledOnce, true, 'readdir should be called once');
|
||||
assert.strictEqual(readdirMock.args[0][0], firstProjectPath, 'readdir should be called with correct arguments');
|
||||
assert.strictEqual(showErrorMessageMock.notCalled, true, 'showErrorMessage should not be called');
|
||||
assert.strictEqual(showMock.calledOnce, true, 'show should be called once');
|
||||
assert.strictEqual(executeCommandMock.calledOnce, true, 'executeCommand should be called once');
|
||||
assert.strictEqual(
|
||||
executeCommandMock.args[0][0],
|
||||
|
|
|
@ -8,7 +8,7 @@ import * as uuid from 'uuid';
|
|||
import * as vscode from 'vscode';
|
||||
import { Constants } from '../../../src/Constants';
|
||||
import { ItemType } from '../../../src/Models';
|
||||
import { AzureBlockchainProject, AzureBlockchainService, Project } from '../../../src/Models/TreeItems';
|
||||
import { AzureBlockchainProject, AzureBlockchainService, Project, Service, ServiceTypes } from '../../../src/Models/TreeItems';
|
||||
import { ConsortiumResourceExplorer } from '../../../src/resourceExplorers';
|
||||
import { GanacheService, TreeManager } from '../../../src/services';
|
||||
import { AzureAccountHelper } from '../../testHelpers/AzureAccountHelper';
|
||||
|
@ -42,7 +42,7 @@ describe('Service Commands', () => {
|
|||
|
||||
describe('connectProject returns project', () => {
|
||||
let selectedDestination: any;
|
||||
let getItemStub: sinon.SinonStub<any[], any> | sinon.SinonStub<unknown[], {}>;
|
||||
let getItemStub: sinon.SinonStub<[ServiceTypes], Service>;
|
||||
let addChildStub: sinon.SinonStub<any, any>;
|
||||
let showQuickPickMock: sinon.SinonStub<any[], any>;
|
||||
let showInputBoxMock: sinon.SinonExpectation;
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import * as truffleDebugUtils from '@truffle/debug-utils';
|
||||
import * as truffleDebugger from '@truffle/debugger';
|
||||
import * as assert from 'assert';
|
||||
import * as sinon from 'sinon';
|
||||
import * as truffleDebugUtils from 'truffle-debug-utils';
|
||||
import * as truffleDebugger from 'truffle-debugger';
|
||||
import * as contractsPrepareHelpers from '../../src/debugAdapter/contracts/contractsPrepareHelpers';
|
||||
import { IContractModel } from '../../src/debugAdapter/models/IContractModel';
|
||||
import RuntimeInterface from '../../src/debugAdapter/runtimeInterface';
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import * as truffleProvider from '@truffle/provider';
|
||||
import * as assert from 'assert';
|
||||
import * as sinon from 'sinon';
|
||||
import * as truffleProvider from 'truffle-provider';
|
||||
import { ConfigurationReader } from '../../src/debugAdapter/configurationReader';
|
||||
import { Web3Wrapper } from '../../src/debugAdapter/web3Wrapper';
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ contract Base {
|
|||
address public Responder;
|
||||
}
|
||||
|
||||
contract HelloBlockchain is Base {
|
||||
contract HelloBlockchain is Base
|
||||
{
|
||||
enum StateType { Request, Respond }
|
||||
enum SwitcherEnum { On, Off }
|
||||
|
||||
|
@ -15,19 +16,23 @@ contract HelloBlockchain is Base {
|
|||
string public RequestMessage;
|
||||
string public ResponseMessage;
|
||||
|
||||
constructor(string memory message) public {
|
||||
constructor(string memory message) public
|
||||
{
|
||||
Requestor = msg.sender;
|
||||
RequestMessage = message;
|
||||
State = StateType.Request;
|
||||
}
|
||||
|
||||
function SendRequest(string memory requestMessage, StateType state) public {
|
||||
function SendRequest(string memory requestMessage, StateType state) public
|
||||
{
|
||||
RequestMessage = requestMessage;
|
||||
State = state;
|
||||
}
|
||||
|
||||
function SendResponse(StateType state, SwitcherEnum flag) public {
|
||||
if (flag == SwitcherEnum.On) {
|
||||
function SendResponse(StateType state, SwitcherEnum flag) public
|
||||
{
|
||||
if (flag == SwitcherEnum.On)
|
||||
{
|
||||
Responder = msg.sender;
|
||||
}
|
||||
|
||||
|
@ -35,7 +40,8 @@ contract HelloBlockchain is Base {
|
|||
}
|
||||
|
||||
function SwitcheToOff(uint completed) public {
|
||||
if(completed > 0) {
|
||||
if(completed > 0)
|
||||
{
|
||||
Flag = SwitcherEnum.Off;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
import * as fs from 'fs-extra';
|
||||
import * as path from 'path';
|
||||
|
||||
export const referenceMnemonic = 'some menmonic some menmonic some menmonic some menmonic some menmonic some menmonic';
|
||||
|
||||
export const referenceCfgContent = 'const HDWalletProvider = require("truffle-hdwallet-provider");'
|
||||
+ 'module.exports = {'
|
||||
+ ' networks: {'
|
||||
|
@ -88,6 +90,7 @@ export const referenceConfiguration = {
|
|||
network_id: '*',
|
||||
port: 123,
|
||||
provider: {
|
||||
mnemonic: referenceMnemonic,
|
||||
raw: 'new HDWalletProvider(fs.readFileSync(\"path\", \"encoding\"), \"url\")',
|
||||
url: 'url',
|
||||
},
|
||||
|
|
|
@ -54,12 +54,16 @@ describe('TruffleConfiguration helper', () => {
|
|||
|
||||
describe('class TruffleConfig', () => {
|
||||
const configPathStub = path.normalize('w:/temp/truffle-config.js');
|
||||
let readFileStub: any;
|
||||
let writeFileStub: any;
|
||||
let readFileStub: sinon.SinonStub<any, any>;
|
||||
let writeFileStub: sinon.SinonStub<any, any>;
|
||||
|
||||
before(() => {
|
||||
readFileStub = sinon.stub(fs, 'readFileSync').returns(testData.referenceCfgContent);
|
||||
readFileStub = sinon.stub(fs, 'readFileSync');
|
||||
writeFileStub = sinon.stub(fs, 'writeFileSync');
|
||||
|
||||
readFileStub.withArgs(configPathStub).returns(testData.referenceCfgContent);
|
||||
readFileStub.withArgs('path').returns(testData.referenceMnemonic);
|
||||
readFileStub.withArgs('path', 'encoding').returns(testData.referenceMnemonic);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
|
@ -186,6 +190,14 @@ describe('class TruffleConfig', () => {
|
|||
|
||||
describe('getConfiguration() in class TruffleConfig', () => {
|
||||
const configPathStub = path.normalize('w:/temp/truffle-config.js');
|
||||
let readFileStub: sinon.SinonStub<any, any>;
|
||||
|
||||
beforeEach(() => {
|
||||
readFileStub = sinon.stub(fs, 'readFileSync');
|
||||
|
||||
readFileStub.withArgs('path').returns(testData.referenceMnemonic);
|
||||
readFileStub.withArgs('path, encoding').returns(testData.referenceMnemonic);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
|
@ -194,7 +206,7 @@ describe('getConfiguration() in class TruffleConfig', () => {
|
|||
it('getConfiguration returns default configuration',
|
||||
async () => {
|
||||
// Arrange
|
||||
sinon.stub(fs, 'readFileSync').returns('');
|
||||
readFileStub.returns('');
|
||||
const truffleConfig = new TruffleConfiguration.TruffleConfig(configPathStub);
|
||||
|
||||
// Act
|
||||
|
@ -219,7 +231,7 @@ describe('getConfiguration() in class TruffleConfig', () => {
|
|||
it('getConfiguration returns configuration without required fields',
|
||||
async () => {
|
||||
// Arrange
|
||||
sinon.stub(fs, 'readFileSync').returns(testData.referenceCfgContent);
|
||||
readFileStub.returns(testData.referenceCfgContent);
|
||||
const truffleConfig = new TruffleConfiguration.TruffleConfig(configPathStub);
|
||||
|
||||
// Act
|
||||
|
@ -247,7 +259,7 @@ describe('getConfiguration() in class TruffleConfig', () => {
|
|||
it('getConfiguration returns configuration with required fields',
|
||||
async () => {
|
||||
// Arrange
|
||||
sinon.stub(fs, 'readFileSync').returns(testData.referenceCfgContentWithDirectories);
|
||||
readFileStub.returns(testData.referenceCfgContentWithDirectories);
|
||||
const truffleConfig = new TruffleConfiguration.TruffleConfig(configPathStub);
|
||||
|
||||
// Act
|
||||
|
|
|
@ -61,4 +61,4 @@ const config = {
|
|||
__dirname: false,
|
||||
}
|
||||
};
|
||||
module.exports = config;
|
||||
module.exports = config;
|
||||
|
|
Загрузка…
Ссылка в новой задаче