UNPKG

@newos/upgradeability-transpiler

Version:

Transpiles Solidity contracts to updgradable versions compatible with NewOs.

103 lines 5.11 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = __importDefault(require("path")); const fs_extra_1 = __importDefault(require("fs-extra")); const lodash_1 = require("lodash"); const ast_utils_1 = require("./solc/ast-utils"); const transpiler_1 = require("./transpiler"); const index_1 = require("./transformations/index"); const get_inheritance_chain_1 = require("./solc/get-inheritance-chain"); function transpileContracts(contracts, artifacts, contractsFolder) { contractsFolder = path_1.default.normalize(contractsFolder); // check that we have valid ast tree for (const art of artifacts) { ast_utils_1.throwIfInvalidNode(art.ast); } // create contract name | id to artifact map for quick access to artifacts const contractsToArtifactsMap = artifacts.reduce((acc, art) => { acc[art.contractName] = art; const contract = ast_utils_1.getContract(art); acc[contract.id] = art; return acc; }, {}); // build a list of all contracts to transpile const contractsToTranspile = [ ...new Set(lodash_1.flatten(contracts.map(contract => get_inheritance_chain_1.getInheritanceChain(contract, contractsToArtifactsMap)))), ].filter(art => { const contractNode = ast_utils_1.getContract(art); return ast_utils_1.isContract(contractNode); }); // build a array of transformations per Solidity file const fileTrans = contractsToTranspile.reduce((acc, art) => { const contractName = art.contractName; const source = art.source; const contractNode = ast_utils_1.getContract(art); if (!acc[art.sourcePath]) { const directive = `\nimport "@newos/upgrades/contracts/Initializable.sol";`; acc[art.sourcePath] = { transformations: [ index_1.appendDirective(art.ast, directive), ...index_1.fixImportDirectives(art, artifacts, contractsToTranspile), ...index_1.purgeExceptContracts(art.ast, contractsToTranspile), ], source: '', }; } acc[art.sourcePath].transformations = [ ...acc[art.sourcePath].transformations, index_1.prependBaseClass(contractNode, source, 'Initializable'), ...index_1.transformParentsNames(contractNode, source, contractsToTranspile), ...index_1.transformConstructor(contractNode, source, contractsToTranspile, contractsToArtifactsMap), ...index_1.purgeVarInits(contractNode, source), index_1.transformContractName(contractNode, source, `${contractName}Upgradeable`), ]; return acc; }, {}); // build a final array of files to return return contractsToTranspile.reduce((acc, art) => { const contractName = art.contractName; const source = art.source; const fileTran = fileTrans[art.sourcePath]; if (!fileTran.source) { fileTran.source = transpiler_1.transpile(source, fileTran.transformations); } const entry = acc.find(o => o.fileName === path_1.default.basename(art.sourcePath)); if (!entry) { const upgradeablePath = path_1.default.normalize(art.sourcePath).replace('.sol', 'Upgradeable.sol'); let patchedFilePath = upgradeablePath; // Truffle stores an absolute file path in a sourcePath of an artifact field // "sourcePath": "/Users/iYalovoy/repo/openzeppelin-sdk/tests/cli/workdir/contracts/Samples.sol" // OpenZeppelin stores relative paths // "sourcePath": "contracts/Foo.sol" // OpenZeppelin sourcePath would start with `contracts` for contracts present in the `contracts` folder of a project // Both Truffle and OpenZeppelin support packages // "sourcePath": "@newos/upgrades/contracts/Initializable.sol", // Relative paths can only be specified using `.` and `..` for both compilers // if path exists then it is a local contract build by Truffle if (fs_extra_1.default.existsSync(art.sourcePath)) { patchedFilePath = upgradeablePath.replace(contractsFolder, ''); } else { if (upgradeablePath.startsWith('contracts')) { patchedFilePath = upgradeablePath.replace('contracts/', ''); } } patchedFilePath = `./contracts/__upgradeable__/${patchedFilePath}`; acc.push({ source: fileTran.source, path: patchedFilePath, fileName: path_1.default.basename(art.sourcePath), contracts: [contractName], }); } else { entry.contracts.push(contractName); } return acc; }, []); } exports.transpileContracts = transpileContracts; //# sourceMappingURL=index.js.map