├── readme_generator ├── compile_README.sh ├── Copyright.md ├── self-doc-gen.sh └── readme-intro.md ├── .gitignore ├── .eslintrc ├── .npmignore ├── ISSUE_TEMPLATE.md ├── CHANGELOG.md ├── .github └── workflows │ └── npmpublish.yml ├── jest.config.js ├── __tests__ ├── test-solidity.js ├── test.sol └── cli.js ├── src ├── index.js ├── compilers │ ├── llvm-c.js │ ├── compilers.js │ ├── job.js │ ├── solidity.js │ └── client-code.js ├── cli │ ├── options.js │ ├── info.js │ ├── spy.js │ └── cli.js ├── server │ ├── server.js │ └── templates │ │ └── main.hbs ├── utils │ ├── texts.js │ ├── utils.js │ └── docker.js ├── networks │ └── networks.js └── dev.js ├── babel.config.js ├── package.json ├── .flowconfig ├── dist ├── compilers │ ├── llvm-c.js │ ├── compilers.js │ └── job.js ├── index.js ├── cli │ ├── options.js │ ├── info.js │ └── spy.js ├── server │ └── server.js ├── networks │ └── networks.js └── utils │ └── texts.js ├── js-templates ├── contract.js.hbs └── contract.rs.hbs └── LICENSE /readme_generator/compile_README.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | OUT=../README.md 4 | 5 | cat ./readme-intro.md > ${OUT} 6 | echo -e "\n---\n\n" >> ${OUT} 7 | ./self-doc-gen.sh >> ${OUT} 8 | echo -e "\n---\n\n" >> ${OUT} 9 | cat ./Copyright.md >> ${OUT} 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /package-lock.json 3 | /.idea/ 4 | /__tests__/test.abi.json 5 | /__tests__/test.tvc 6 | /__tests__/testContract.js 7 | /__tests__/23cf51cff01453d5b62ce9a4e3cfe193f50aacc62c5c46843f8416a132f81ba3.tvc 8 | /__tests__/job.sh 9 | /__tests__/test.code 10 | /__tests__/test.result 11 | /reinstall.sh 12 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "rules": { 4 | "indent": [ 5 | "error", 6 | 4 7 | ], 8 | "arrow-body-style": "off", 9 | "no-console": "off", 10 | "no-continue": "off", 11 | }, 12 | "env": { 13 | "browser": true, 14 | "node": true, 15 | "jest": true 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /package-lock.json 3 | /.idea/ 4 | /__tests__/test.abi.json 5 | /__tests__/test.tvc 6 | /__tests__/testContract.js 7 | /__tests__/23cf51cff01453d5b62ce9a4e3cfe193f50aacc62c5c46843f8416a132f81ba3.tvc 8 | /__tests__/job.sh 9 | /__tests__/test.code 10 | /__tests__/test.result 11 | /reinstall.sh 12 | /readme_generator/ 13 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## My Environment 2 | 3 | * __ton-dev-cli version__: 4 | * __Operating System__: 5 | 6 | 7 | ## Steps to reproduce 8 | 9 | 1. 10 | 2. 11 | 3. 12 | 13 | __Problem__: 14 | 15 | 16 | __Expected result__: 17 | 18 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | All notable changes to this project will be documented in this file. 3 | 4 | ## 0.17.6 5 | ### Fixed 6 | - fixed `sol` duplicate error messages in console 7 | 8 | ## 0.17.5 – May 6, 2020 9 | ### Breaking Compatibility 10 | - Commands `test` and `trace` has been removed due to `tonmon`. 11 | 12 | ### Fixed 13 | - Command `addr` failed on masterchain addresses. 14 | 15 | -------------------------------------------------------------------------------- /readme_generator/Copyright.md: -------------------------------------------------------------------------------- 1 | Copyright 2018-2020 TON DEV SOLUTIONS LTD. 2 | 3 | Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 4 | this file except in compliance with the License. You may obtain a copy of the 5 | License at: https://www.ton.dev/licenses 6 | 7 | Unless required by applicable law or agreed to in writing, software 8 | distributed under the License is distributed on an "AS IS" BASIS, 9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | See the License for the specific TON DEV software governing permissions and 11 | limitations under the License. 12 | -------------------------------------------------------------------------------- /readme_generator/self-doc-gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TON="tondev" 4 | 5 | which ${TON} &>/dev/null || { 6 | echo "ERROR! ${TON} is not installed" 7 | exit 1 8 | } 9 | 10 | echo "## Complete help for version: $( ${TON} -V )" 11 | echo 12 | echo "#### \`${TON} -help\`" 13 | echo 14 | 15 | echo '```' 16 | ${TON} -h 17 | echo '```' 18 | 19 | echo 20 | echo "### _subcommands help:_"; 21 | 22 | for cmd in $( ${TON} -h | grep -A5000 -m1 -e '^Commands:' | tail -n+2 | sed 's/|/ /' | cut -f 3 -d " " - ); do 23 | echo 24 | echo "#### \`${TON} ${cmd} --help\`" 25 | echo 26 | 27 | echo '```' 28 | ${TON} ${cmd} -h 29 | 30 | echo '```' 31 | # echo 32 | done 33 | -------------------------------------------------------------------------------- /.github/workflows/npmpublish.yml: -------------------------------------------------------------------------------- 1 | name: npm publish 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | publish-npm: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-node@v1 13 | with: 14 | node-version: 12 15 | registry-url: https://registry.npmjs.org/ 16 | - run: npm publish 17 | env: 18 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 19 | 20 | send-discord-msg: 21 | needs: publish-npm 22 | runs-on: ubuntu-latest 23 | steps: 24 | - name: Discord notification 25 | env: 26 | DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} 27 | uses: Ilshidur/action-discord@master 28 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | 16 | module.exports = { 17 | moduleFileExtensions: [ 18 | 'js', 19 | ], 20 | modulePathIgnorePatterns: [ 21 | 'init.js', 22 | ], 23 | transform: { 24 | '^.+\\.js$': 'babel-jest', 25 | }, 26 | testPathIgnorePatterns: [ 27 | "/node_modules/", 28 | "Contract.js$" 29 | ], 30 | }; 31 | -------------------------------------------------------------------------------- /__tests__/test-solidity.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | 16 | import { Solidity } from "../src/compilers/solidity"; 17 | import { Dev } from "../src/dev"; 18 | const path = require('path'); 19 | 20 | jest.setTimeout(60_000); 21 | 22 | test('Solidity Compiler', async () => { 23 | // const dev = new Dev(); 24 | // await Solidity.build(dev, [ 25 | // path.resolve(__dirname, 'test') 26 | // ], { 27 | // clientLevel: 'deploy', 28 | // clientLanguages: ['js'], 29 | // }) 30 | }); 31 | 32 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 4 | /* 5 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 6 | * 7 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 8 | * this file except in compliance with the License. You may obtain a copy of the 9 | * License at: https://www.ton.dev/licenses 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific TON DEV software governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | 19 | import { handleCommandLine } from "./cli/cli"; 20 | import { Dev } from "./dev"; 21 | 22 | 23 | async function main() { 24 | const dev = new Dev(); 25 | await handleCommandLine(dev, process.argv); 26 | } 27 | 28 | (async () => { 29 | try { 30 | await main(); 31 | process.exit(0); 32 | } catch (error) { 33 | if (error.message) { 34 | console.error(`\n${error.message}`); 35 | } else { 36 | console.error(`\n${error}`); 37 | } 38 | process.exit(1); 39 | } 40 | })(); 41 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | 16 | const presets = [ 17 | ["@babel/preset-flow"], 18 | ]; 19 | const plugins = [ 20 | ["@babel/plugin-proposal-class-properties"], 21 | ["@babel/plugin-proposal-export-default-from"], 22 | ["@babel/plugin-proposal-export-namespace-from"], 23 | ["@babel/plugin-proposal-nullish-coalescing-operator"], 24 | ["@babel/plugin-proposal-numeric-separator"], 25 | ["@babel/plugin-proposal-optional-chaining"], 26 | ["@babel/plugin-syntax-bigint"], 27 | ["@babel/plugin-syntax-dynamic-import"], 28 | ["@babel/plugin-transform-modules-commonjs"], 29 | ]; 30 | 31 | module.exports = {presets, plugins}; 32 | -------------------------------------------------------------------------------- /src/compilers/llvm-c.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | 16 | import { ClientCode } from "./client-code"; 17 | import type { ClientCodeGenerationOptions, ClientCodeLanguageType } from "./client-code"; 18 | import { Compilers } from "./compilers"; 19 | import { CompilersJob } from "./job"; 20 | 21 | export type BuildOptions = { 22 | files: string[], 23 | clientCode: { 24 | [ClientCodeLanguageType]: ClientCodeGenerationOptions, 25 | } 26 | }; 27 | 28 | export class LLVMC { 29 | static async build(compilers: Compilers, options: BuildOptions) { 30 | const job = CompilersJob.create(compilers, { 31 | keepContent: false, 32 | }); 33 | 34 | await ClientCode.generate(job, options.clientCode); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ton-dev-cli", 3 | "version": "0.17.7", 4 | "keywords": [ 5 | "TON", 6 | "Javascript", 7 | "API", 8 | "Client" 9 | ], 10 | "author": "TON DEV SOLUTIONS LTD.", 11 | "license": "SEE LICENSE IN LICENSE", 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/tonlabs/ton-dev-cli.git" 15 | }, 16 | "homepage": "https://ton.dev/node-se", 17 | "scripts": { 18 | "babel": "babel src --out-dir dist --source-maps inline", 19 | "flow": "flow", 20 | "test": "jest", 21 | "ton": "node ./dist/index.js", 22 | "npm install": "npm install", 23 | "gendoc": "cd ./readme_generator/ && ./compile_README.sh" 24 | }, 25 | "bin": { 26 | "tondev": "./dist/index.js", 27 | "ton": "./dist/index.js" 28 | }, 29 | "husky": { 30 | "hooks": { 31 | "pre-commit": "npm run babel && git add dist" 32 | } 33 | }, 34 | "dependencies": { 35 | "@babel/runtime": "^7.9.6", 36 | "cli-progress": "^3.8.2", 37 | "colors": "^1.4.0", 38 | "commander": "^5.1.0", 39 | "cors": "^2.8.5", 40 | "dockerode": "^3.0.2", 41 | "express": "^4.17.1", 42 | "handlebars": "^4.5.3", 43 | "ton-client-node-js": "^0" 44 | }, 45 | "devDependencies": { 46 | "@babel/cli": "^7.8.4", 47 | "@babel/core": "^7.9.6", 48 | "@babel/plugin-proposal-class-properties": "^7.8.3", 49 | "@babel/plugin-proposal-decorators": "^7.8.3", 50 | "@babel/plugin-proposal-export-default-from": "^7.8.3", 51 | "@babel/plugin-proposal-export-namespace-from": "^7.8.3", 52 | "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", 53 | "@babel/plugin-proposal-numeric-separator": "^7.8.3", 54 | "@babel/plugin-proposal-optional-chaining": "^7.9.0", 55 | "@babel/plugin-syntax-bigint": "^7.8.3", 56 | "@babel/plugin-syntax-dynamic-import": "^7.8.3", 57 | "@babel/plugin-transform-modules-commonjs": "^7.9.6", 58 | "@babel/preset-flow": "^7.8.3", 59 | "babel-eslint": "^10.0.3", 60 | "eslint": "^6.7.2", 61 | "eslint-plugin-import": "^2.18.2", 62 | "eslint-plugin-jsx-a11y": "^6.2.3", 63 | "flow": "^0.2.3", 64 | "flow-bin": "0.123.0", 65 | "husky": "^4.2.5", 66 | "jest": "^26.0.1" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/cli/options.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | 16 | import type { CompilersWithNetworks } from "../dev"; 17 | import { Dev } from "../dev"; 18 | import { Network } from "../networks/networks"; 19 | 20 | export type NetworksOptions = { 21 | networks?: boolean | string, 22 | } 23 | 24 | export type CompilersOptions = { 25 | compilers?: boolean, 26 | } 27 | 28 | export type CompilersWithNetworksOptions = CompilersOptions & NetworksOptions; 29 | 30 | export type InfoOptions = { 31 | available?: boolean 32 | } 33 | 34 | export type SetupOptions = CompilersWithNetworksOptions; 35 | 36 | export type StartOptions = CompilersWithNetworksOptions; 37 | export type StopOptions = CompilersWithNetworksOptions; 38 | export type RestartOptions = CompilersWithNetworksOptions; 39 | export type RecreateOptions = CompilersWithNetworksOptions; 40 | export type CleanOptions = { 41 | networks: boolean, 42 | compilers: boolean, 43 | containers: boolean, 44 | } 45 | 46 | export type UseOptions = CompilersWithNetworksOptions; 47 | export type SetNetworkOptions = { 48 | newName?: string; 49 | port?: string, 50 | dbPort?: string, 51 | } 52 | 53 | export type SolOptions = { 54 | clientLanguages?: string, 55 | clientLevel?: string, 56 | jsModule?: string, 57 | } 58 | 59 | export type WebOptions = { 60 | port: string, 61 | } 62 | 63 | function findNetworks(dev: Dev, options: NetworksOptions): ?(Network[]) { 64 | const names = options.networks; 65 | if (!names) { 66 | return null; 67 | } 68 | if (typeof names === 'boolean') { 69 | return dev.networks; 70 | } 71 | return dev.networksFromNames(names.split(',')); 72 | } 73 | 74 | export function compilersWithNetworks( 75 | dev: Dev, 76 | options: CompilersWithNetworksOptions 77 | ): CompilersWithNetworks { 78 | let compilers = !!options.compilers; 79 | 80 | let networks = findNetworks(dev, options); 81 | if (!compilers && !networks) { 82 | compilers = true; 83 | networks = dev.networks; 84 | } 85 | return { 86 | compilers, 87 | networks: networks || [] 88 | }; 89 | } 90 | 91 | -------------------------------------------------------------------------------- /src/server/server.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | 16 | // @flow 17 | 18 | import type { WebOptions } from "../cli/options"; 19 | import { Dev } from "../dev"; 20 | import { inputLine } from "../utils/utils"; 21 | 22 | const express = require('express'); 23 | const cors = require('cors'); 24 | import Handlebars from 'handlebars'; 25 | 26 | const path = require('path'); 27 | const fs = require('fs'); 28 | 29 | function applyTemplate(name: string, context: any): Promise { 30 | const templatePath = path.resolve(__dirname, '..', '..', 'src', 'server', 'templates', `${name}.hbs`); 31 | const templateText = fs.readFileSync(templatePath, { encoding: 'utf8' }); 32 | const template = Handlebars.compile(templateText, { 33 | noEscape: true, 34 | }); 35 | return template(context); 36 | } 37 | 38 | export class TONDevWebConsole { 39 | dev: Dev; 40 | options: WebOptions; 41 | 42 | constructor(dev: Dev, options: WebOptions) { 43 | this.dev = dev; 44 | this.options = options; 45 | } 46 | 47 | start() { 48 | const app = express(); 49 | app.use(express.json()); 50 | app.use(cors()); 51 | app.get('/', this.main.bind(this)); 52 | app.listen({ port: this.options.port }, () => { 53 | const uri = `http://localhost:${this.options.port}`; 54 | console.debug(`TON Dev Web Console started on ${uri}`); 55 | }); 56 | } 57 | 58 | async main(req: any, res: any) { 59 | try { 60 | await res.send(applyTemplate('main', this.dev)); 61 | res.end(); 62 | } catch (error) { 63 | console.log('[Web Console] request failed', error); 64 | await res.json({ 65 | jsonrpc: '2.0', 66 | id: 1, 67 | error: { 68 | code: Number.parseInt(error && error.code) || 1, 69 | message: error.message || error.toString(), 70 | data: error 71 | } 72 | }); 73 | } 74 | } 75 | } 76 | 77 | export async function web(dev: Dev, options: WebOptions) { 78 | const server = new TONDevWebConsole(dev, options); 79 | server.start(); 80 | return inputLine(); 81 | } 82 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | .*/dist/.* 11 | 12 | ; Ignore duplicate module providers 13 | ; For RN Apps installed via npm, "Libraries" folder is inside 14 | ; "node_modules/react-native" but in the source repo it is in the root 15 | .*/Libraries/react-native/React.js 16 | 17 | ; Ignore polyfills 18 | .*/Libraries/polyfills/.* 19 | 20 | ; Ignore metro 21 | .*/node_modules/metro/.* 22 | 23 | ; Ignore graphql 24 | .*/node_modules/ton-client-js/ 25 | .*/node_modules/graphql/.* 26 | .*/node_modules/graphql-tag/lib/graphql-tag.umd.js.flow.* 27 | 28 | ; Ignore Electron packager 29 | .*/node_modules/electron-packager/.* 30 | 31 | [untyped] 32 | ; Ignore react-native-tab-view 33 | .*/node_modules/react-native-tab-view/.* 34 | 35 | [include] 36 | 37 | [libs] 38 | node_modules/react-native/Libraries/react-native/react-native-interface.js 39 | node_modules/react-native/flow/ 40 | node_modules/react-native/flow-github/ 41 | 42 | [options] 43 | emoji=true 44 | 45 | esproposal.optional_chaining=enable 46 | esproposal.nullish_coalescing=enable 47 | 48 | module.system=haste 49 | module.system.haste.use_name_reducers=true 50 | # get basename 51 | module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1' 52 | # strip .js or .js.flow suffix 53 | module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1' 54 | # strip .ios suffix 55 | module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1' 56 | module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1' 57 | module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1' 58 | module.system.haste.paths.blacklist=.*/__tests__/.* 59 | module.system.haste.paths.blacklist=.*/__mocks__/.* 60 | module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/Animated/src/polyfills/.* 61 | module.system.haste.paths.whitelist=/node_modules/react-native/Libraries/.* 62 | 63 | munge_underscores=true 64 | 65 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' 66 | 67 | module.file_ext=.js 68 | module.file_ext=.jsx 69 | module.file_ext=.json 70 | module.file_ext=.native.js 71 | 72 | suppress_type=$FlowIssue 73 | suppress_type=$FlowFixMe 74 | suppress_type=$FlowFixMeProps 75 | suppress_type=$FlowFixMeState 76 | 77 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 78 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 79 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 80 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 81 | 82 | [version] 83 | 84 | -------------------------------------------------------------------------------- /src/compilers/compilers.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | // @flow 16 | import type { ContainerDef, DockerContainer } from "../utils/docker"; 17 | import { DevDocker } from "../utils/docker"; 18 | import { userIdentifier } from "../utils/utils"; 19 | 20 | export type CompilersConfig = { 21 | version: string, 22 | } 23 | 24 | 25 | export class Compilers implements ContainerDef { 26 | static imagePrefix = 'tonlabs/compilers'; 27 | static containerPrefix = 'tonlabs-compilers'; 28 | static defaultConfig: CompilersConfig = Object.freeze({ 29 | version: 'latest' 30 | }); 31 | 32 | version: string; 33 | requiredImage: string; 34 | containerName: string; 35 | mountDestination: string; 36 | 37 | constructor(config: CompilersConfig) { 38 | this.setConfig(config); 39 | } 40 | 41 | setConfig(config: CompilersConfig) { 42 | this.version = config.version; 43 | this.requiredImage = `${Compilers.imagePrefix}:${config.version}`; 44 | this.containerName = `${Compilers.containerPrefix}-${userIdentifier}`; 45 | this.mountDestination = '/projects'; 46 | } 47 | 48 | getConfig(): CompilersConfig { 49 | return { 50 | version: this.version, 51 | } 52 | } 53 | 54 | async createContainer(docker: DevDocker): Promise { 55 | throw new Error('Internal error: invalid call to Compilers.createContainer'); 56 | } 57 | 58 | async createContainerMountedTo(hostPath: string, docker: DevDocker): Promise { 59 | await docker.ensureImage(this.requiredImage); 60 | const existing = await docker.getContainerInfos(); 61 | let name = ''; 62 | let index = 0; 63 | do { 64 | name = `${this.containerName}${index > 0 ? `-${index}` : ''}`; 65 | index += 1; 66 | } while (existing.find(x => DevDocker.hasName(x, name))); 67 | docker.dropCache(); 68 | return docker.client.createContainer({ 69 | name, 70 | interactive: true, 71 | Image: this.requiredImage, 72 | Tty: true, 73 | Env: ['USER_AGREEMENT=yes'], 74 | HostConfig: { 75 | Mounts: [ 76 | { 77 | Type: 'bind', 78 | Source: hostPath, 79 | Target: this.mountDestination, 80 | }, 81 | ], 82 | }, 83 | }); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/utils/texts.js: -------------------------------------------------------------------------------- 1 | const texts = { 2 | agreementConfirmation: ` 3 | This Agreement takes effect when you input a “YES” and press Enter 4 | or, if earlier, when you use any of the TON DEV Software: `, 5 | agreementRejected: '\n\nLicense terms were not accepted.\n', 6 | agreementAccepted: '\n\nLicense terms were accepted.\n', 7 | dockerVersionRequired: "Docker version required ^17", 8 | noTonDevImages: 'There are no TON Dev Images', 9 | noTonDevContainers: 'There are no TON Dev Containers', 10 | done: ' Done.', 11 | netsHeader: 'Local nets:', 12 | compilerHeader: 'Compilers:', 13 | availableVersions: 'Available versions:', 14 | containerDoesNotExists(name) { 15 | return `Container [${name}] does not exists. Creating...`; 16 | }, 17 | imageDoesNotExists(name) { 18 | return `Image [${name}] is missing. Pulling (please wait)...`; 19 | }, 20 | containerCanNotBeCreated(name) { 21 | return `Container [${name}] can not be created`; 22 | }, 23 | containerHaveBeenRemoved(id) { 24 | return `Container [${id} have been removed.`; 25 | }, 26 | imageHaveBeenRemoved(id) { 27 | return `Image [${id} have been removed.`; 28 | }, 29 | sourceFileNotFound(name) { 30 | return `Source file [${name}] not found.`; 31 | }, 32 | usageHeader(version) { 33 | return `TON Labs Dev Tools ${version}`; 34 | }, 35 | invalidOption(arg) { 36 | return `Invalid option: ${arg}`; 37 | }, 38 | usage: `usage: tondev command { argument ... } 39 | 40 | Options: 41 | -p, --port Set local port number for local net 42 | -n, --net Set local net name to which command applied, can be specified multiple times 43 | -i, --images Apply command only to docker images 44 | -c, --containers Apply command only to docker containers 45 | -js, --JavaScript Generate additional JavaScript code 46 | 47 | 48 | Commands: 49 | sol Build TON contract from solidity source code 50 | start Start local net (if net name does not specified the all nets will be started) 51 | stop Stop compilers and all nets 52 | info Show current status of compilers and nets 53 | setup Looking for a required prerequisites and setup required additional components 54 | clean Remove all TON Dev docker containers and images 55 | use Select version for compilers and nets 56 | 57 | Copyright 2018-2020 TON DEV SOLUTIONS LTD. 58 | Licensed under the SOFTWARE EVALUATION License (https://www.ton.dev/licenses) 59 | `, 60 | tonDevImages() { 61 | return `Images:`; 62 | }, 63 | tonDevContainers() { 64 | return `Containers:`; 65 | }, 66 | netHeader(name) { 67 | return `${name} network/blockchain:`; 68 | }, 69 | usedVersion(version) { 70 | return ` Used version: ${version}`; 71 | }, 72 | netHostPort(port) { 73 | return ` Bound to host port: ${port}`; 74 | }, 75 | netArangoHostPort(port) { 76 | return ` Arango DB is bound to host port: ${port}`; 77 | }, 78 | }; 79 | 80 | export { texts }; 81 | -------------------------------------------------------------------------------- /src/cli/info.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | // @flow 16 | 17 | 18 | import { Compilers } from "../compilers/compilers"; 19 | import { Dev } from "../dev"; 20 | import { Network } from "../networks/networks"; 21 | import type { DContainerInfo } from "../utils/docker"; 22 | import { texts } from "../utils/texts"; 23 | import { httpsGetJson, version } from "../utils/utils"; 24 | import type { InfoOptions } from "./options"; 25 | 26 | export async function infoCommand(dev: Dev, options: InfoOptions) { 27 | async function listTags(image: string): Promise { 28 | const url = `https://registry.hub.docker.com/v2/repositories/${image}/tags/`; 29 | const tags = await httpsGetJson(url); 30 | return tags.results.map(x => x.name).sort(); 31 | } 32 | 33 | async function showAvailableVersions(imagePrefix: string) { 34 | console.log(` ${imagePrefix}: ${(await listTags(imagePrefix)).join(', ')}`); 35 | } 36 | 37 | function mapContainerName(name: string): string { 38 | return name.startsWith('/') ? name.substr(1) : name; 39 | } 40 | 41 | async function showContainerInfo(name: string) { 42 | const info: ?DContainerInfo = await dev.docker.findContainerInfo(name); 43 | if (info) { 44 | console.log(` Docker image: ${info.Image}`); 45 | console.log(` Docker container: ${info.Names.map(mapContainerName).join(', ')} ${info.State}`); 46 | } else { 47 | console.log(` Docker container missing: ${name}`); 48 | } 49 | } 50 | 51 | console.log(texts.usageHeader(version)); 52 | 53 | for (let i = 0; i < dev.networks.length; i += 1) { 54 | const network = dev.networks[i]; 55 | console.log(); 56 | console.log(texts.netHeader(network.name)); 57 | console.log(); 58 | console.log(texts.usedVersion(network.version)); 59 | console.log(texts.netHostPort(network.hostPort)); 60 | if (network.arangoHostPort !== '') { 61 | console.log(texts.netArangoHostPort(network.arangoHostPort)); 62 | } 63 | await showContainerInfo(network.containerName); 64 | } 65 | console.log(); 66 | console.log(texts.compilerHeader); 67 | console.log(); 68 | console.log(texts.usedVersion(dev.compilers.version)); 69 | await showContainerInfo(dev.compilers.containerName); 70 | 71 | 72 | if (options.available) { 73 | console.log(); 74 | console.log(texts.availableVersions); 75 | console.log(); 76 | await showAvailableVersions(Compilers.imagePrefix); 77 | await showAvailableVersions(Network.imagePrefix); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/server/templates/main.hbs: -------------------------------------------------------------------------------- 1 | 2 | TON Dev Local 3 | 4 | 78 | 83 | 84 |
85 | 86 | 87 | 88 | 95 | 96 |

TON Dev Console

89 | Compilers: 90 | 0.13.0 91 | 0.14.0 92 | 0.14.1-rc 93 | 0.15.0-rc 94 |
97 |
98 |
99 |

Networks

100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | {{#each networks}} 108 | 109 | 110 | 111 | 112 | 113 | 114 | {{/each}} 115 |
NameVersionPortDB Port
{{name}}{{version}}{{hostPort}}{{arangoHostPort}}
116 |
117 | 118 | -------------------------------------------------------------------------------- /src/compilers/job.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | 16 | // @flow 17 | 18 | import { Dev } from "../dev"; 19 | import type { DockerContainer } from "../utils/docker"; 20 | import type { PathJoin } from "../utils/utils"; 21 | import { bindPathJoinTo, run } from "../utils/utils"; 22 | const os = require('os'); 23 | 24 | class CompilersJob { 25 | dev: Dev; 26 | container: DockerContainer; 27 | hostPath: PathJoin; 28 | guestPath: PathJoin; 29 | 30 | constructor( 31 | dev: Dev, 32 | container: DockerContainer, 33 | srcPath: PathJoin, 34 | dstPath: PathJoin, 35 | ) { 36 | this.dev = dev; 37 | this.container = container; 38 | this.hostPath = srcPath; 39 | this.guestPath = dstPath; 40 | } 41 | 42 | static async create(dev: Dev, path: string) { 43 | const hostPath = bindPathJoinTo(path); 44 | const {container, guestPath} = await dev.getCompilersMountedTo(hostPath()); 45 | return new CompilersJob(dev, container, hostPath, guestPath); 46 | } 47 | 48 | async run(...args: string[]) { 49 | const container = this.container; 50 | if (os.platform() === 'win32') { 51 | return run('docker', 'exec', container.id, ...args); 52 | } 53 | return new Promise((resolve, reject) => { 54 | container.exec({ 55 | Cmd: args, 56 | Tty: true, 57 | AttachStdin: true, 58 | AttachStdout: true, 59 | AttachStderr: true, 60 | }, (err, exec) => { 61 | if (err) { 62 | reject(err); 63 | return; 64 | } 65 | exec.start((err, stream) => { 66 | if (err) { 67 | reject(err); 68 | return; 69 | } 70 | 71 | container.modem.demuxStream(stream, process.stdout, process.stderr); 72 | 73 | const checkForResult = () => { 74 | exec.inspect((err, data) => { 75 | if (err) { 76 | reject(err); 77 | return; 78 | } 79 | if (data.Running) { 80 | setTimeout(checkForResult, 10); 81 | } else { 82 | resolve(data); 83 | } 84 | }); 85 | }; 86 | checkForResult(); 87 | }); 88 | }); 89 | }); 90 | } 91 | 92 | } 93 | 94 | export { 95 | CompilersJob 96 | } 97 | -------------------------------------------------------------------------------- /src/networks/networks.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | 16 | // @flow 17 | 18 | import type { ContainerDef, DockerContainer, DPortBindings } from "../utils/docker"; 19 | import { DevDocker } from "../utils/docker"; 20 | import { userIdentifier } from "../utils/utils"; 21 | 22 | export type NetworkConfig = { 23 | name: string, 24 | version: string, 25 | hostPort: string, 26 | arangoHostPort: string, 27 | }; 28 | 29 | class Network implements ContainerDef { 30 | static imagePrefix = 'tonlabs/local-node'; 31 | static containerPrefix = 'tonlabs-local-node'; 32 | static defaultName = 'default'; 33 | static defaultConfig: NetworkConfig = Object.freeze({ 34 | name: 'default', 35 | version: 'latest', 36 | hostPort: '80', 37 | arangoHostPort: '', 38 | }); 39 | static defaultArangoPort = '8529'; 40 | 41 | name: string; 42 | version: string; 43 | hostPort: string; 44 | arangoHostPort: string; 45 | requiredImage: string; 46 | containerName: string; 47 | 48 | constructor(config: NetworkConfig) { 49 | this.setConfig(config); 50 | } 51 | 52 | setConfig(config: NetworkConfig) { 53 | this.name = config.name; 54 | this.version = config.version; 55 | this.hostPort = config.hostPort || ''; 56 | this.arangoHostPort = config.arangoHostPort || ''; 57 | this.requiredImage = `${Network.imagePrefix}:${config.version}`; 58 | const suffix = config.name !== Network.defaultName ? `-${config.name}` : ''; 59 | this.containerName = `${Network.containerPrefix}-${userIdentifier}${suffix}`; 60 | } 61 | 62 | getConfig(): NetworkConfig { 63 | return { 64 | name: this.name, 65 | version: this.version, 66 | hostPort: this.hostPort, 67 | arangoHostPort: this.arangoHostPort 68 | } 69 | } 70 | 71 | async createContainer(docker: DevDocker): Promise { 72 | const ports: DPortBindings = { 73 | '80/tcp': [ 74 | { 75 | HostIp: '', 76 | HostPort: `${this.hostPort}`, 77 | }, 78 | ], 79 | }; 80 | if (this.arangoHostPort !== '') { 81 | ports['8529/tcp'] = [ 82 | { 83 | HostIp: '', 84 | HostPort: this.arangoHostPort, 85 | }, 86 | ] 87 | } 88 | return docker.client.createContainer({ 89 | name: this.containerName, 90 | interactive: true, 91 | Image: this.requiredImage, 92 | Env: ['USER_AGREEMENT=yes'], 93 | HostConfig: { 94 | PortBindings: ports, 95 | }, 96 | }); 97 | } 98 | } 99 | 100 | 101 | export { 102 | Network 103 | } 104 | -------------------------------------------------------------------------------- /dist/compilers/llvm-c.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.LLVMC = void 0; 7 | 8 | var _clientCode = require("./client-code"); 9 | 10 | var _compilers = require("./compilers"); 11 | 12 | var _job = require("./job"); 13 | 14 | /* 15 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 16 | * 17 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 18 | * this file except in compliance with the License. You may obtain a copy of the 19 | * License at: https://www.ton.dev/licenses 20 | * 21 | * Unless required by applicable law or agreed to in writing, software 22 | * distributed under the License is distributed on an "AS IS" BASIS, 23 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24 | * See the License for the specific TON DEV software governing permissions and 25 | * limitations under the License. 26 | * 27 | */ 28 | class LLVMC { 29 | static async build(compilers, options) { 30 | const job = _job.CompilersJob.create(compilers, { 31 | keepContent: false 32 | }); 33 | 34 | await _clientCode.ClientCode.generate(job, options.clientCode); 35 | } 36 | 37 | } 38 | 39 | exports.LLVMC = LLVMC; 40 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21waWxlcnMvbGx2bS1jLmpzIl0sIm5hbWVzIjpbIkxMVk1DIiwiYnVpbGQiLCJjb21waWxlcnMiLCJvcHRpb25zIiwiam9iIiwiQ29tcGlsZXJzSm9iIiwiY3JlYXRlIiwia2VlcENvbnRlbnQiLCJDbGllbnRDb2RlIiwiZ2VuZXJhdGUiLCJjbGllbnRDb2RlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBZUE7O0FBRUE7O0FBQ0E7O0FBbEJBOzs7Ozs7Ozs7Ozs7OztBQTJCTyxNQUFNQSxLQUFOLENBQVk7QUFDZixlQUFhQyxLQUFiLENBQW1CQyxTQUFuQixFQUF5Q0MsT0FBekMsRUFBZ0U7QUFDNUQsVUFBTUMsR0FBRyxHQUFHQyxrQkFBYUMsTUFBYixDQUFvQkosU0FBcEIsRUFBK0I7QUFDdkNLLE1BQUFBLFdBQVcsRUFBRTtBQUQwQixLQUEvQixDQUFaOztBQUlBLFVBQU1DLHVCQUFXQyxRQUFYLENBQW9CTCxHQUFwQixFQUF5QkQsT0FBTyxDQUFDTyxVQUFqQyxDQUFOO0FBQ0g7O0FBUGMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IDIwMTgtMjAyMCBUT04gREVWIFNPTFVUSU9OUyBMVEQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIFNPRlRXQVJFIEVWQUxVQVRJT04gTGljZW5zZSAodGhlIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlXG4gKiB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGVcbiAqIExpY2Vuc2UgYXQ6IGh0dHBzOi8vd3d3LnRvbi5kZXYvbGljZW5zZXNcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIFRPTiBERVYgc29mdHdhcmUgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENsaWVudENvZGUgfSBmcm9tIFwiLi9jbGllbnQtY29kZVwiO1xuaW1wb3J0IHR5cGUgeyBDbGllbnRDb2RlR2VuZXJhdGlvbk9wdGlvbnMsIENsaWVudENvZGVMYW5ndWFnZVR5cGUgfSBmcm9tIFwiLi9jbGllbnQtY29kZVwiO1xuaW1wb3J0IHsgQ29tcGlsZXJzIH0gZnJvbSBcIi4vY29tcGlsZXJzXCI7XG5pbXBvcnQgeyBDb21waWxlcnNKb2IgfSBmcm9tIFwiLi9qb2JcIjtcblxuZXhwb3J0IHR5cGUgQnVpbGRPcHRpb25zID0ge1xuICAgIGZpbGVzOiBzdHJpbmdbXSxcbiAgICBjbGllbnRDb2RlOiB7XG4gICAgICAgIFtDbGllbnRDb2RlTGFuZ3VhZ2VUeXBlXTogQ2xpZW50Q29kZUdlbmVyYXRpb25PcHRpb25zLFxuICAgIH1cbn07XG5cbmV4cG9ydCBjbGFzcyBMTFZNQyB7XG4gICAgc3RhdGljIGFzeW5jIGJ1aWxkKGNvbXBpbGVyczogQ29tcGlsZXJzLCBvcHRpb25zOiBCdWlsZE9wdGlvbnMpIHtcbiAgICAgICAgY29uc3Qgam9iID0gQ29tcGlsZXJzSm9iLmNyZWF0ZShjb21waWxlcnMsIHtcbiAgICAgICAgICAgIGtlZXBDb250ZW50OiBmYWxzZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgQ2xpZW50Q29kZS5nZW5lcmF0ZShqb2IsIG9wdGlvbnMuY2xpZW50Q29kZSk7XG4gICAgfVxufVxuIl19 -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /* 4 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 5 | * 6 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 7 | * this file except in compliance with the License. You may obtain a copy of the 8 | * License at: https://www.ton.dev/licenses 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific TON DEV software governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | "use strict"; 18 | 19 | var _cli = require("./cli/cli"); 20 | 21 | var _dev = require("./dev"); 22 | 23 | async function main() { 24 | const dev = new _dev.Dev(); 25 | await (0, _cli.handleCommandLine)(dev, process.argv); 26 | } 27 | 28 | (async () => { 29 | try { 30 | await main(); 31 | process.exit(0); 32 | } catch (error) { 33 | if (error.message) { 34 | console.error(`\n${error.message}`); 35 | } else { 36 | console.error(`\n${error}`); 37 | } 38 | 39 | process.exit(1); 40 | } 41 | })(); 42 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJtYWluIiwiZGV2IiwiRGV2IiwicHJvY2VzcyIsImFyZ3YiLCJleGl0IiwiZXJyb3IiLCJtZXNzYWdlIiwiY29uc29sZSJdLCJtYXBwaW5ncyI6IkFBQUE7O0FBR0E7Ozs7Ozs7Ozs7Ozs7Ozs7QUFlQTs7QUFDQTs7QUFHQSxlQUFlQSxJQUFmLEdBQXNCO0FBQ2xCLFFBQU1DLEdBQUcsR0FBRyxJQUFJQyxRQUFKLEVBQVo7QUFDQSxRQUFNLDRCQUFrQkQsR0FBbEIsRUFBdUJFLE9BQU8sQ0FBQ0MsSUFBL0IsQ0FBTjtBQUNIOztBQUVELENBQUMsWUFBWTtBQUNULE1BQUk7QUFDQSxVQUFNSixJQUFJLEVBQVY7QUFDQUcsSUFBQUEsT0FBTyxDQUFDRSxJQUFSLENBQWEsQ0FBYjtBQUNILEdBSEQsQ0FHRSxPQUFPQyxLQUFQLEVBQWM7QUFDWixRQUFJQSxLQUFLLENBQUNDLE9BQVYsRUFBbUI7QUFDZkMsTUFBQUEsT0FBTyxDQUFDRixLQUFSLENBQWUsS0FBSUEsS0FBSyxDQUFDQyxPQUFRLEVBQWpDO0FBQ0gsS0FGRCxNQUVPO0FBQ0hDLE1BQUFBLE9BQU8sQ0FBQ0YsS0FBUixDQUFlLEtBQUlBLEtBQU0sRUFBekI7QUFDSDs7QUFDREgsSUFBQUEsT0FBTyxDQUFDRSxJQUFSLENBQWEsQ0FBYjtBQUNIO0FBQ0osQ0FaRCIsInNvdXJjZXNDb250ZW50IjpbIiMhL3Vzci9iaW4vZW52IG5vZGVcblxuXG4vKlxuICogQ29weXJpZ2h0IDIwMTgtMjAyMCBUT04gREVWIFNPTFVUSU9OUyBMVEQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIFNPRlRXQVJFIEVWQUxVQVRJT04gTGljZW5zZSAodGhlIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlXG4gKiB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGVcbiAqIExpY2Vuc2UgYXQ6IGh0dHBzOi8vd3d3LnRvbi5kZXYvbGljZW5zZXNcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIFRPTiBERVYgc29mdHdhcmUgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IGhhbmRsZUNvbW1hbmRMaW5lIH0gZnJvbSBcIi4vY2xpL2NsaVwiO1xuaW1wb3J0IHsgRGV2IH0gZnJvbSBcIi4vZGV2XCI7XG5cblxuYXN5bmMgZnVuY3Rpb24gbWFpbigpIHtcbiAgICBjb25zdCBkZXYgPSBuZXcgRGV2KCk7XG4gICAgYXdhaXQgaGFuZGxlQ29tbWFuZExpbmUoZGV2LCBwcm9jZXNzLmFyZ3YpO1xufVxuXG4oYXN5bmMgKCkgPT4ge1xuICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IG1haW4oKTtcbiAgICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChlcnJvci5tZXNzYWdlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBcXG4ke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBcXG4ke2Vycm9yfWApO1xuICAgICAgICB9XG4gICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICB9XG59KSgpO1xuIl19 -------------------------------------------------------------------------------- /src/cli/spy.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | // @flow 16 | 17 | //TODO: import { TONClient } from "ton-client-node-js"; 18 | import { Dev } from "../dev"; 19 | import { Network } from "../networks/networks"; 20 | import { texts } from "../utils/texts"; 21 | import { inputLine, version } from "../utils/utils"; 22 | 23 | async function createClient(netAddress: string) { 24 | return {}; 25 | //TODO: return TONClient.create({ 26 | // servers: [netAddress] 27 | // }); 28 | } 29 | 30 | const transactionProjection = ` 31 | id 32 | account_addr 33 | in_message { 34 | header { 35 | ...on MessageHeaderExtOutMsgInfoVariant { 36 | ExtOutMsgInfo { 37 | dst { 38 | ...on MsgAddressExtAddrNoneVariant { AddrNone { None } } 39 | ...on MsgAddressExtAddrExternVariant { AddrExtern { AddrExtern } } 40 | } 41 | } 42 | } 43 | ...on MessageHeaderExtInMsgInfoVariant { 44 | ExtInMsgInfo { 45 | src { 46 | ...on MsgAddressExtAddrExternVariant { AddrExtern { AddrExtern } } 47 | ...on MsgAddressExtAddrNoneVariant { AddrNone { None } } 48 | } 49 | } 50 | } 51 | ...on MessageHeaderIntMsgInfoVariant { 52 | IntMsgInfo { 53 | value { Grams } 54 | src { 55 | ...on MsgAddressIntAddrVarVariant { AddrVar { address } } 56 | ...on MsgAddressIntAddrStdVariant { AddrStd { address } } 57 | ...on MsgAddressIntAddrNoneVariant { AddrNone { None } } 58 | } 59 | } 60 | } 61 | } 62 | } 63 | `; 64 | 65 | async function spy(dev: Dev, names: string[]) { 66 | console.log(texts.usageHeader(version)); 67 | await Promise.all(dev.networks.map(async (net: Network) => { 68 | const netAddress = `http://0.0.0.0:${net.hostPort || '80'}`; 69 | console.log(`Spy for ${net.name} at ${netAddress}`); 70 | const localNet = await createClient(netAddress); 71 | const accounts = await localNet.queries.accounts.query({}, 'id', [{ path: 'id', direction: 'ASC' }], 11); 72 | console.log('Accounts:'); 73 | accounts.slice(0, 10).forEach(x => console.log(` ${x.id}`)); 74 | if (accounts.length > 10) { 75 | console.log(' and more...'); 76 | } 77 | console.log(''); 78 | console.log('Looking for transactions and more... Press [Enter] to stop...'); 79 | localNet.queries.transactions.subscribe({}, transactionProjection, (e, tr) => { 80 | console.log('TRX:', tr.id); 81 | const msg = tr.in_message; 82 | const intMsg = msg.header.IntMsgInfo; 83 | if (intMsg) { 84 | console.log(' ', `${tr.account_addr} <- ${intMsg.value.Grams} <- ${intMsg.src.AddrStd.address}`); 85 | } else { 86 | console.log(' ', `${tr.account_addr} <- EXT`); 87 | } 88 | }); 89 | localNet.queries.accounts.subscribe({}, 'id', (e, d) => { 90 | console.log('ACC:', d.id); 91 | }); 92 | })); 93 | 94 | await inputLine(); 95 | } 96 | 97 | 98 | export { spy }; 99 | -------------------------------------------------------------------------------- /js-templates/contract.js.hbs: -------------------------------------------------------------------------------- 1 | {{!-- 2 | 3 | Result Type Doc 4 | 5 | --}} 6 | {{#*inline "resultTypeDoc"}} 7 | {{#if hasOutputs}} 8 | /** 9 | * @typedef {{@root.className}}_{{name}} 10 | * @type {object} 11 | {{#each outputs}} 12 | * @property {{LB}}{{jsType}}{{RB}} {{name}} {{#if isSameJsType}}{{else}} ({{type}}){{/if}} 13 | {{/each}} 14 | */ 15 | 16 | {{/if}} 17 | {{/inline}} 18 | {{!-- 19 | 20 | Input Doc 21 | 22 | --}} 23 | {{#*inline "inputDoc"}} 24 | {{#if hasInputs}} 25 | * @param {object} params 26 | {{#each inputs}} 27 | * @param {{LB}}{{jsType}}{{RB}} params.{{name}}{{#if isSameJsType}}{{else}} ({{type}}){{/if}} 28 | {{/each}} 29 | {{/if}} 30 | {{/inline}} 31 | {{!-- 32 | 33 | Function Doc 34 | 35 | --}} 36 | {{#*inline "funcDoc"}} 37 | /** 38 | {{> inputDoc }} 39 | {{#if hasOutputs}} 40 | * @return {{LB}}Promise.<{{@root.className}}_{{name}}>{{RB}} 41 | {{/if}} 42 | */ 43 | {{/inline}} 44 | {{!-- 45 | 46 | Contract 47 | 48 | --}} 49 | // 50 | // This file was generated using TON Labs developer tools. 51 | // 52 | 53 | const abi = {{abiJson}}; 54 | 55 | const pkg = { 56 | abi, 57 | imageBase64: '{{imageBase64}}', 58 | }; 59 | 60 | {{#if jsModuleEs}}export {{#if jsModuleEsDefault}}default {{/if}}{{/if}}class {{className}} { 61 | /** 62 | * @param {TONClient} client 63 | * @param {string} address can be null if contract will be deployed 64 | * @param {TONKeyPairData} keys 65 | */ 66 | constructor(client, address, keys) { 67 | this.client = client; 68 | this.address = address; 69 | this.keys = keys; 70 | this.package = pkg; 71 | this.abi = abi; 72 | } 73 | 74 | {{#if isDeploy}} 75 | {{#with constructor}} 76 | /** 77 | {{#if hasInputs}} 78 | * @param {object} constructorParams 79 | {{#each inputs}} 80 | * @param {{LB}}{{jsType}}{{RB}} constructorParams.{{name}}{{#if isSameJsType}}{{else}} ({{type}}){{/if}} 81 | {{/each}} 82 | {{/if}} 83 | {{#if hasData}} 84 | * @param {object} initParams 85 | {{#each data}} 86 | * @param {{LB}}{{jsType}}{{RB}} initParams.{{name}}{{#if isSameJsType}}{{else}} ({{type}}){{/if}} 87 | {{/each}} 88 | {{/if}} 89 | */ 90 | async deploy({{#if hasInputs}}constructorParams{{/if}}{{#if hasInputsAndData}}, {{/if}}{{#if hasData}}initParams{{/if}}) { 91 | if (!this.keys) { 92 | this.keys = await this.client.crypto.ed25519Keypair(); 93 | } 94 | this.address = (await this.client.contracts.deploy({ 95 | package: pkg, 96 | constructorParams{{#if hasInputs}}{{else}}: {}{{/if}}, 97 | initParams{{#if hasData}}{{else}}: {}{{/if}}, 98 | keyPair: this.keys, 99 | })).address; 100 | } 101 | {{/with}} 102 | {{/if}} 103 | 104 | /** 105 | * @param {string} functionName 106 | * @param {object} input 107 | * @return {Promise.} 108 | */ 109 | async run(functionName, input) { 110 | const result = await this.client.contracts.run({ 111 | address: this.address, 112 | functionName, 113 | abi, 114 | input, 115 | keyPair: this.keys, 116 | }); 117 | return result.output; 118 | } 119 | 120 | /** 121 | * @param {string} functionName 122 | * @param {object} input 123 | * @return {Promise.} 124 | */ 125 | async runLocal(functionName, input) { 126 | const result = await this.client.contracts.runLocal({ 127 | address: this.address, 128 | functionName, 129 | abi, 130 | input, 131 | keyPair: this.keys, 132 | }); 133 | return result.output; 134 | } 135 | 136 | {{#each functions}} 137 | {{> resultTypeDoc}} 138 | {{> funcDoc}} 139 | {{name}}({{#if hasInputs}}params{{/if}}) { 140 | return this.run('{{name}}', {{#if hasInputs}}params{{else}}{}{{/if}}); 141 | } 142 | 143 | {{> funcDoc}} 144 | {{name}}Local({{#if hasInputs}}params{{/if}}) { 145 | return this.runLocal('{{name}}', {{#if hasInputs}}params{{else}}{}{{/if}}); 146 | } 147 | 148 | {{/each}} 149 | } 150 | 151 | {{className}}.package = pkg; 152 | {{#if jsModuleNode}} 153 | 154 | module.exports = {{#unless jsModuleNodeDefault}}{{LB}} {{/unless}}{{className}}{{#unless jsModuleNodeDefault}} {{RB}}{{/unless}}; 155 | {{/if}} 156 | -------------------------------------------------------------------------------- /js-templates/contract.rs.hbs: -------------------------------------------------------------------------------- 1 | {{!-- 2 | 3 | Result Type Doc 4 | 5 | --}} 6 | {{#*inline "resultTypeDoc"}} 7 | {{#if hasOutputs}} 8 | /** 9 | * @typedef {{@root.className}}_{{name}} 10 | * @type {object} 11 | {{#each outputs}} 12 | * @property {{LB}}{{jsType}}{{RB}} {{name}} {{#if isSameJsType}}{{else}} ({{type}}){{/if}} 13 | {{/each}} 14 | */ 15 | 16 | {{/if}} 17 | {{/inline}} 18 | {{!-- 19 | 20 | Input Doc 21 | 22 | --}} 23 | {{#*inline "inputDoc"}} 24 | {{#if hasInputs}} 25 | * @param {object} params 26 | {{#each inputs}} 27 | * @param {{LB}}{{jsType}}{{RB}} params.{{name}}{{#if isSameJsType}}{{else}} ({{type}}){{/if}} 28 | {{/each}} 29 | {{/if}} 30 | {{/inline}} 31 | {{!-- 32 | 33 | Function Doc 34 | 35 | --}} 36 | {{#*inline "funcDoc"}} 37 | /** 38 | {{> inputDoc }} 39 | {{#if hasOutputs}} 40 | * @return {{LB}}Promise.<{{@root.className}}_{{name}}>{{RB}} 41 | {{/if}} 42 | */ 43 | {{/inline}} 44 | {{!-- 45 | 46 | Contract 47 | 48 | --}} 49 | // 50 | // This file was generated using TON Labs developer tools. 51 | // 52 | 53 | const abi: &str = "{{abiJson}}"; 54 | 55 | const pkg = { 56 | abi, 57 | imageBase64: "{{imageBase64}}", 58 | }; 59 | 60 | pub struct {{className}} { 61 | pub client: &TONClient; 62 | pub address: String; 63 | pub keys: TONKeyPair; 64 | pub package: TONContractPackage; 65 | pub abi: &str; 66 | } 67 | 68 | impl {{className}} { 69 | /** 70 | * @param {TONClient} client 71 | * @param {string} address can be null if contract will be deployed 72 | * @param {TONKeyPairData} keys 73 | */ 74 | from(client: &TONClient, address: &String, keys: &TONKeyPair) -> Self { 75 | 76 | this.client = client; 77 | this.address = address; 78 | this.keys = keys; 79 | this.package = pkg; 80 | this.abi = abi; 81 | } 82 | 83 | {{#if isDeploy}} 84 | {{#with constructor}} 85 | /** 86 | {{#if hasInputs}} 87 | * @param {object} constructorParams 88 | {{#each inputs}} 89 | * @param {{LB}}{{jsType}}{{RB}} constructorParams.{{name}}{{#if isSameJsType}}{{else}} ({{type}}){{/if}} 90 | {{/each}} 91 | {{/if}} 92 | {{#if hasData}} 93 | * @param {object} initParams 94 | {{#each data}} 95 | * @param {{LB}}{{jsType}}{{RB}} initParams.{{name}}{{#if isSameJsType}}{{else}} ({{type}}){{/if}} 96 | {{/each}} 97 | {{/if}} 98 | */ 99 | async deploy({{#if hasInputs}}constructorParams{{/if}}{{#if hasInputsAndData}}, {{/if}}{{#if hasData}}initParams{{/if}}) { 100 | if (!this.keys) { 101 | this.keys = await this.client.crypto.ed25519Keypair(); 102 | } 103 | this.address = (await this.client.contracts.deploy({ 104 | package: pkg, 105 | constructorParams{{#if hasInputs}}{{else}}: {}{{/if}}, 106 | initParams{{#if hasData}}{{else}}: {}{{/if}}, 107 | keyPair: this.keys, 108 | })).address; 109 | } 110 | {{/with}} 111 | {{/if}} 112 | 113 | /** 114 | * @param {string} functionName 115 | * @param {object} input 116 | * @return {Promise.} 117 | */ 118 | async run(functionName, input) { 119 | const result = await this.client.contracts.run({ 120 | address: this.address, 121 | functionName, 122 | abi, 123 | input, 124 | keyPair: this.keys, 125 | }); 126 | return result.output; 127 | } 128 | 129 | /** 130 | * @param {string} functionName 131 | * @param {object} input 132 | * @return {Promise.} 133 | */ 134 | async runLocal(functionName, input) { 135 | const result = await this.client.contracts.runLocal({ 136 | address: this.address, 137 | functionName, 138 | abi, 139 | input, 140 | keyPair: this.keys, 141 | }); 142 | return result.output; 143 | } 144 | 145 | {{#each functions}} 146 | {{> resultTypeDoc}} 147 | {{> funcDoc}} 148 | {{name}}({{#if hasInputs}}params{{/if}}) { 149 | return this.run('{{name}}', {{#if hasInputs}}params{{else}}{}{{/if}}); 150 | } 151 | 152 | {{> funcDoc}} 153 | {{name}}Local({{#if hasInputs}}params{{/if}}) { 154 | return this.runLocal('{{name}}', {{#if hasInputs}}params{{else}}{}{{/if}}); 155 | } 156 | 157 | {{/each}} 158 | } 159 | 160 | {{className}}.package = pkg; 161 | -------------------------------------------------------------------------------- /__tests__/test.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.0; 2 | 3 | /** 4 | * @title Standard ERC20 token 5 | * 6 | * @dev Implementation of the basic standard token. 7 | * https://eips.ethereum.org/EIPS/eip-20 8 | * Originally based on code by FirstBlood: 9 | * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol 10 | * 11 | * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for 12 | * all accounts just by listening to said events. Note that this isn't required by the specification, and other 13 | * compliant implementations may not do it. 14 | */ 15 | 16 | contract ERC20 { 17 | mapping (address => uint256) private _balances; 18 | 19 | mapping (address => mapping (address => uint256)) private _allowed; 20 | 21 | uint256 private _totalSupply; 22 | uint256 public _foo; 23 | 24 | constructor(uint256 totalSupply, address owner) public payable { 25 | _totalSupply = totalSupply; 26 | _balances[owner] = totalSupply; 27 | return; 28 | } 29 | 30 | /** 31 | * @dev Total number of tokens in existence 32 | */ 33 | function totalSupply() public view returns (uint256) { 34 | return _totalSupply; 35 | } 36 | 37 | /** 38 | * @dev Gets the balance of the specified address. 39 | * @param owner The address to query the balance of. 40 | * @return A uint256 representing the amount owned by the passed address. 41 | */ 42 | function balanceOf(address owner) public view returns (uint256) { 43 | return _balances[owner]; 44 | } 45 | 46 | /** 47 | * @dev Function to check the amount of tokens that an owner allowed to a spender. 48 | * @param owner address The address which owns the funds. 49 | * @param spender address The address which will spend the funds. 50 | * @return A uint256 specifying the amount of tokens still available for the spender. 51 | */ 52 | function allowance(address owner, address spender) public view returns (uint256) { 53 | return _allowed[owner][spender]; 54 | } 55 | 56 | /** 57 | * @dev Transfer token to a specified address 58 | * @param to The address to transfer to. 59 | * @param value The amount to be transferred. 60 | */ 61 | function transfer(address to, uint256 value, address msg_sender) public returns (bool) { 62 | //_transfer(msg.sender, to, value); 63 | address from = msg_sender; 64 | _balances[from] = _balances[from] - value; 65 | _balances[to] = _balances[to] + value; 66 | return true; 67 | } 68 | 69 | /** 70 | * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. 71 | * Beware that changing an allowance with this method brings the risk that someone may use both the old 72 | * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this 73 | * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: 74 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 75 | * @param spender The address which will spend the funds. 76 | * @param value The amount of tokens to be spent. 77 | */ 78 | function approve(address spender, uint256 value, address msg_sender) public returns (bool) { 79 | address owner = msg_sender; 80 | //require(spender != address(0)); 81 | //require(owner != address(0)); 82 | 83 | _allowed[owner][spender] = value; 84 | //_approve(msg.sender, spender, value); 85 | return true; 86 | } 87 | 88 | /** 89 | * @dev Transfer tokens from one address to another. 90 | * Note that while this function emits an Approval event, this is not required as per the specification, 91 | * and other compliant implementations may not emit the event. 92 | * @param from address The address which you want to send tokens from 93 | * @param to address The address which you want to transfer to 94 | * @param value uint256 the amount of tokens to be transferred 95 | */ 96 | function transferFrom(address from, address to, uint256 value, address msg_sender) public returns (bool) { 97 | //_transfer(from, to, value); 98 | _balances[from] = _balances[from] - value; 99 | _balances[to] = _balances[to] + value; 100 | // SafeMath sub -> simple subtraction 101 | //_approve(from, msg.sender, _allowed[from][msg.sender] - value); 102 | _allowed[from][msg_sender] = _allowed[from][msg_sender] - value; 103 | return true; 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /src/compilers/solidity.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | // @flow 16 | 17 | 18 | import { Dev } from "../dev"; 19 | import type { PathJoin } from "../utils/utils"; 20 | import { parseFileArg } from "../utils/utils"; 21 | import type { ClientCodeOptions } from "./client-code"; 22 | import { ClientCode } from "./client-code"; 23 | import { CompilersJob } from "./job"; 24 | 25 | const fs = require('fs'); 26 | 27 | export type SolidityBuildOptions = ClientCodeOptions; 28 | 29 | type SolidityFileArg = { 30 | dir: PathJoin, 31 | name: { 32 | base: string, 33 | sol: string, 34 | tvc: string, 35 | code: string, 36 | abi: string, 37 | package: string, 38 | result: string, 39 | }, 40 | } 41 | 42 | export function parseSolidityFileArg(fileArg: string, fileMustExists: boolean): SolidityFileArg { 43 | const parsed = parseFileArg(fileArg, '.sol', fileMustExists); 44 | return { 45 | dir: parsed.dir, 46 | name: { 47 | base: parsed.base, 48 | sol: parsed.name, 49 | tvc: `${parsed.base}.tvc`, 50 | code: `${parsed.base}.code`, 51 | abi: `${parsed.base}.abi.json`, 52 | package: `${parsed.base}Package`, 53 | result: `${parsed.base}.result`, 54 | }, 55 | }; 56 | } 57 | 58 | export class Solidity { 59 | static async build(dev: Dev, files: string[], options: SolidityBuildOptions) { 60 | const sol = new Solidity(dev, files, options); 61 | await sol.build(); 62 | } 63 | 64 | dev: Dev; 65 | files: string[]; 66 | options: SolidityBuildOptions; 67 | 68 | constructor(dev: Dev, files: string[], options: SolidityBuildOptions) { 69 | this.dev = dev; 70 | this.files = files; 71 | this.options = options; 72 | } 73 | 74 | async build() { 75 | for (let i = 0; i < this.files.length; i += 1) { 76 | const file = parseSolidityFileArg(this.files[i], true); 77 | const job = await CompilersJob.create(this.dev, file.dir()); 78 | this.prepareBuildBatch(file, job); 79 | await job.run('sh', job.guestPath('job.sh')); 80 | this.cleanBuildResults(file, job); 81 | await ClientCode.generate([this.files[i]], this.options); 82 | } 83 | } 84 | 85 | prepareBuildBatchForFile(file: SolidityFileArg, batch: string[]) { 86 | const { name } = file; 87 | if (this.dev.compilers.getConfig().version === 'latest') { 88 | batch.push( 89 | `solc ${name.sol}`, 90 | `tvm_linker compile ${name.code} --lib /usr/bin/stdlib_sol.tvm --abi-json ${name.abi} > ${name.result}` 91 | ); 92 | } else { 93 | batch.push( 94 | `solc ${name.sol} --tvm > ${name.code}`, 95 | `solc ${name.sol} --tvm_abi > ${name.abi} || solc ${name.sol} --tvm-abi > ${name.abi}`, 96 | `tvm_linker compile ${name.code} --lib /usr/bin/stdlib_sol.tvm --abi-json ${name.abi} > ${name.result}` 97 | ); 98 | } 99 | } 100 | 101 | prepareBuildBatch(file: SolidityFileArg, job: CompilersJob) { 102 | const batch = []; 103 | batch.push(`cd ${job.guestPath()}`); 104 | this.prepareBuildBatchForFile(file, batch); 105 | fs.writeFileSync(job.hostPath('job.sh'), batch.join('\n')); 106 | } 107 | 108 | cleanBuildResults(file: SolidityFileArg, job: CompilersJob) { 109 | const { name } = file; 110 | const linkerResult = fs.readFileSync(job.hostPath(name.result), { encoding: 'utf8' }); 111 | const tvcFile = (/Saved contract to file\s*(.*\.tvc)/gi.exec(linkerResult) || [])[1]; 112 | if (!tvcFile) { 113 | console.log(linkerResult); 114 | process.exit(1) 115 | } 116 | fs.renameSync(job.hostPath(tvcFile), job.hostPath(name.tvc)); 117 | fs.unlinkSync(job.hostPath('job.sh')); 118 | fs.unlinkSync(job.hostPath(name.result)); 119 | fs.unlinkSync(job.hostPath(name.code)); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /readme_generator/readme-intro.md: -------------------------------------------------------------------------------- 1 | # ton-dev-cli 2 | 3 | TON Labs Dev Command Line Tool 4 | 5 | See [https://docs.ton.dev](https://docs.ton.dev) for documentation. 6 | Also check our [Youtube channel](https://www.youtube.com/channel/UC9kJ6DKaxSxk6T3lEGdq-Gg) for tutorials. 7 | 8 | --- 9 | ## Dependencies 10 | - `Node.js` >= 10.x installed 11 | 12 | - `Docker` >= 19.x installed 13 | 14 | ## Install 15 | 16 | ```shell 17 | npm install -g ton-dev-cli 18 | ``` 19 | 20 | or 21 | 22 | ```shell 23 | sudo npm install -g ton-dev-cli 24 | ``` 25 | 26 | # Basic operations 27 | 28 | ## Invocation 29 | 30 | While installed globally, `ton-dev-cli` package places its executable `tondev` into system path, so you could 31 | use it everywhere in your file system as a main command to invoke the tool. 32 | 33 | Type: 34 | `tondev` `info` (or just `tondev`) - to see current status 35 | `tondev` `-V` - to see `ton-dev-cli` version 36 | `tondev` `-a` - to see versions of the compilers and node containers available in DockerHub registry 37 | `tondev` `-h` or `tondev` `--help` for the help about usage, options and subcommands 38 | 39 | 40 | >_You can use `-h` or `--help` option with any subcommand to get extended help about its usage. Also full help content is included in this document below._ 41 | 42 | 43 | ## Initialization 44 | 45 | In order to get started, run: `tondev setup` 46 | 47 | The command triggers Docker image pull from DockerHub registry and launches the corresponding containers: 48 | 49 | - tonlabs-compilers-\ that is used for building solidity contracts 50 | - tonlabs-local-node-\ is a local TON node container runs compiled contracts. 51 | 52 | You can specify additional options to customize the installation: 53 | - `-n`, `--networks` 54 | - `-m`, `--compilers` 55 | 56 | ## Managing containers 57 | 58 | To start and stop both containers, use the `tondev start` and `tondev stop` commands. 59 | Use these commands to save machine resources. 60 | 61 | - `restart` restarts the installed containers. 62 | - `recreate` removes containers and re-creates them again. Start tondev utility again after. 63 | 64 | - `-n`, `--networks [names]` applies the command to specified network(s) (use comma to separate) 65 | - `-m`, `--compilers applies` the command to the compiler kit container 66 | 67 | ## Building local nodes network 68 | 69 | To test your contract at multiple nodes, create a network. A network consists 70 | of multiple inter-connected local nodes. 71 | 72 | A single run of `tondev setup` creates a single local node listening to port 80. 73 | 74 | In order to add another node: 75 | 76 | ```shell 77 | tondev add anotherNode 78 | ​tondev set --port 81 anotherNode 79 | ``` 80 | 81 | `tondev add` adds another node to network config. By default it uses port 80. 82 | 83 | Given that multiple nodes cannot use the same port, reset the port with `tondev set -p`. 84 | 85 | > Note: You can add multiple nodes simultaneously by separating names with a space. 86 | 87 | ## Exposing local node ArangoDB 88 | 89 | It is useful to expose ArangoDB built in each local node. To do it, run: 90 | 91 | ```shell 92 | tondev set --db-port 8881 anotherNode 93 | ``` 94 | 95 | Instead of the port number you can specify "bind" to use the default Arango DB 96 | port or "unbind" to stop exposing the port. 97 | 98 | ## Renaming local node 99 | 100 | In order to rename a node, run: 101 | 102 | ```shell 103 | tondev set --new-name newName oldName 104 | ``` 105 | 106 | To remove a node run `tondev remove anotherNode` or `tondev rm anotherNode`. 107 | 108 | ## Compiling Solidity 109 | 110 | Solidity contracts are compiled with the following command: 111 | 112 | ```shell 113 | tondev sol [options] [files...] 114 | ``` 115 | 116 | The following options are available: 117 | 118 | - `-l`, `--client-languages ` to generate client code for languages: "js" (use comma to separate several languages) 119 | - `-L`, `--client-level ` client code level: "run" to run only, "deploy" to run and deploy (includes an imageBase64 of a binary contract) 120 | 121 | ## Switching compiler versions 122 | 123 | tondev CLI allows switching between compiler versions; run: 124 | 125 | ```shell 126 | tondev use 0.14.0 127 | ``` 128 | 129 | The command pulls a relevant Docker container. You can also run: 130 | 131 | ``` 132 | tondev use [options] to use specified version for containers 133 | ``` 134 | 135 | ## Removing containers 136 | 137 | In order to remove Docker containers and images related to TON Dev, run: 138 | 139 | ```shell 140 | tondev clean 141 | ``` 142 | 143 | The following options are available to customize the command: 144 | 145 | - `-n`, `--networks` clean local node docker containers and images 146 | - `-m`, `--compilers` clean compilers docker containers and images 147 | - `-c`, `--containers` clean containers only (default: false) 148 | 149 | If no option is specified, the command removes all TON Dev docker containers and images. 150 | 151 | ## Key Pair Generation 152 | 153 | 154 | command: `keys` 155 | 156 | Usage: `tondev keys|k` [options] 157 | 158 | Generate random Key Pair 159 | -------------------------------------------------------------------------------- /dist/cli/options.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.compilersWithNetworks = compilersWithNetworks; 7 | 8 | var _dev = require("../dev"); 9 | 10 | var _networks = require("../networks/networks"); 11 | 12 | /* 13 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 14 | * 15 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 16 | * this file except in compliance with the License. You may obtain a copy of the 17 | * License at: https://www.ton.dev/licenses 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific TON DEV software governing permissions and 23 | * limitations under the License. 24 | * 25 | */ 26 | function findNetworks(dev, options) { 27 | const names = options.networks; 28 | 29 | if (!names) { 30 | return null; 31 | } 32 | 33 | if (typeof names === 'boolean') { 34 | return dev.networks; 35 | } 36 | 37 | return dev.networksFromNames(names.split(',')); 38 | } 39 | 40 | function compilersWithNetworks(dev, options) { 41 | let compilers = !!options.compilers; 42 | let networks = findNetworks(dev, options); 43 | 44 | if (!compilers && !networks) { 45 | compilers = true; 46 | networks = dev.networks; 47 | } 48 | 49 | return { 50 | compilers, 51 | networks: networks || [] 52 | }; 53 | } 54 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvb3B0aW9ucy5qcyJdLCJuYW1lcyI6WyJmaW5kTmV0d29ya3MiLCJkZXYiLCJvcHRpb25zIiwibmFtZXMiLCJuZXR3b3JrcyIsIm5ldHdvcmtzRnJvbU5hbWVzIiwic3BsaXQiLCJjb21waWxlcnNXaXRoTmV0d29ya3MiLCJjb21waWxlcnMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFnQkE7O0FBQ0E7O0FBakJBOzs7Ozs7Ozs7Ozs7OztBQThEQSxTQUFTQSxZQUFULENBQXNCQyxHQUF0QixFQUFnQ0MsT0FBaEMsRUFBd0U7QUFDcEUsUUFBTUMsS0FBSyxHQUFHRCxPQUFPLENBQUNFLFFBQXRCOztBQUNBLE1BQUksQ0FBQ0QsS0FBTCxFQUFZO0FBQ1IsV0FBTyxJQUFQO0FBQ0g7O0FBQ0QsTUFBSSxPQUFPQSxLQUFQLEtBQWlCLFNBQXJCLEVBQWdDO0FBQzVCLFdBQU9GLEdBQUcsQ0FBQ0csUUFBWDtBQUNIOztBQUNELFNBQU9ILEdBQUcsQ0FBQ0ksaUJBQUosQ0FBc0JGLEtBQUssQ0FBQ0csS0FBTixDQUFZLEdBQVosQ0FBdEIsQ0FBUDtBQUNIOztBQUVNLFNBQVNDLHFCQUFULENBQ0hOLEdBREcsRUFFSEMsT0FGRyxFQUdrQjtBQUNyQixNQUFJTSxTQUFTLEdBQUcsQ0FBQyxDQUFDTixPQUFPLENBQUNNLFNBQTFCO0FBRUEsTUFBSUosUUFBUSxHQUFHSixZQUFZLENBQUNDLEdBQUQsRUFBTUMsT0FBTixDQUEzQjs7QUFDQSxNQUFJLENBQUNNLFNBQUQsSUFBYyxDQUFDSixRQUFuQixFQUE2QjtBQUN6QkksSUFBQUEsU0FBUyxHQUFHLElBQVo7QUFDQUosSUFBQUEsUUFBUSxHQUFHSCxHQUFHLENBQUNHLFFBQWY7QUFDSDs7QUFDRCxTQUFPO0FBQ0hJLElBQUFBLFNBREc7QUFFSEosSUFBQUEsUUFBUSxFQUFFQSxRQUFRLElBQUk7QUFGbkIsR0FBUDtBQUlIIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAyMDE4LTIwMjAgVE9OIERFViBTT0xVVElPTlMgTFRELlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBTT0ZUV0FSRSBFVkFMVUFUSU9OIExpY2Vuc2UgKHRoZSBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZVxuICogdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlXG4gKiBMaWNlbnNlIGF0OiBodHRwczovL3d3dy50b24uZGV2L2xpY2Vuc2VzXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBUT04gREVWIHNvZnR3YXJlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IENvbXBpbGVyc1dpdGhOZXR3b3JrcyB9IGZyb20gXCIuLi9kZXZcIjtcbmltcG9ydCB7IERldiB9IGZyb20gXCIuLi9kZXZcIjtcbmltcG9ydCB7IE5ldHdvcmsgfSBmcm9tIFwiLi4vbmV0d29ya3MvbmV0d29ya3NcIjtcblxuZXhwb3J0IHR5cGUgTmV0d29ya3NPcHRpb25zID0ge1xuICAgIG5ldHdvcmtzPzogYm9vbGVhbiB8IHN0cmluZyxcbn1cblxuZXhwb3J0IHR5cGUgQ29tcGlsZXJzT3B0aW9ucyA9IHtcbiAgICBjb21waWxlcnM/OiBib29sZWFuLFxufVxuXG5leHBvcnQgdHlwZSBDb21waWxlcnNXaXRoTmV0d29ya3NPcHRpb25zID0gQ29tcGlsZXJzT3B0aW9ucyAmIE5ldHdvcmtzT3B0aW9ucztcblxuZXhwb3J0IHR5cGUgSW5mb09wdGlvbnMgPSB7XG4gICAgYXZhaWxhYmxlPzogYm9vbGVhblxufVxuXG5leHBvcnQgdHlwZSBTZXR1cE9wdGlvbnMgPSBDb21waWxlcnNXaXRoTmV0d29ya3NPcHRpb25zO1xuXG5leHBvcnQgdHlwZSBTdGFydE9wdGlvbnMgPSBDb21waWxlcnNXaXRoTmV0d29ya3NPcHRpb25zO1xuZXhwb3J0IHR5cGUgU3RvcE9wdGlvbnMgPSBDb21waWxlcnNXaXRoTmV0d29ya3NPcHRpb25zO1xuZXhwb3J0IHR5cGUgUmVzdGFydE9wdGlvbnMgPSBDb21waWxlcnNXaXRoTmV0d29ya3NPcHRpb25zO1xuZXhwb3J0IHR5cGUgUmVjcmVhdGVPcHRpb25zID0gQ29tcGlsZXJzV2l0aE5ldHdvcmtzT3B0aW9ucztcbmV4cG9ydCB0eXBlIENsZWFuT3B0aW9ucyA9IHtcbiAgICBuZXR3b3JrczogYm9vbGVhbixcbiAgICBjb21waWxlcnM6IGJvb2xlYW4sXG4gICAgY29udGFpbmVyczogYm9vbGVhbixcbn1cblxuZXhwb3J0IHR5cGUgVXNlT3B0aW9ucyA9IENvbXBpbGVyc1dpdGhOZXR3b3Jrc09wdGlvbnM7XG5leHBvcnQgdHlwZSBTZXROZXR3b3JrT3B0aW9ucyA9IHtcbiAgICBuZXdOYW1lPzogc3RyaW5nO1xuICAgIHBvcnQ/OiBzdHJpbmcsXG4gICAgZGJQb3J0Pzogc3RyaW5nLFxufVxuXG5leHBvcnQgdHlwZSBTb2xPcHRpb25zID0ge1xuICAgIGNsaWVudExhbmd1YWdlcz86IHN0cmluZyxcbiAgICBjbGllbnRMZXZlbD86IHN0cmluZyxcbiAgICBqc01vZHVsZT86IHN0cmluZyxcbn1cblxuZXhwb3J0IHR5cGUgV2ViT3B0aW9ucyA9IHtcbiAgICBwb3J0OiBzdHJpbmcsXG59XG5cbmZ1bmN0aW9uIGZpbmROZXR3b3JrcyhkZXY6IERldiwgb3B0aW9uczogTmV0d29ya3NPcHRpb25zKTogPyhOZXR3b3JrW10pIHtcbiAgICBjb25zdCBuYW1lcyA9IG9wdGlvbnMubmV0d29ya3M7XG4gICAgaWYgKCFuYW1lcykge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBuYW1lcyA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHJldHVybiBkZXYubmV0d29ya3M7XG4gICAgfVxuICAgIHJldHVybiBkZXYubmV0d29ya3NGcm9tTmFtZXMobmFtZXMuc3BsaXQoJywnKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb21waWxlcnNXaXRoTmV0d29ya3MoXG4gICAgZGV2OiBEZXYsXG4gICAgb3B0aW9uczogQ29tcGlsZXJzV2l0aE5ldHdvcmtzT3B0aW9uc1xuKTogQ29tcGlsZXJzV2l0aE5ldHdvcmtzIHtcbiAgICBsZXQgY29tcGlsZXJzID0gISFvcHRpb25zLmNvbXBpbGVycztcblxuICAgIGxldCBuZXR3b3JrcyA9IGZpbmROZXR3b3JrcyhkZXYsIG9wdGlvbnMpO1xuICAgIGlmICghY29tcGlsZXJzICYmICFuZXR3b3Jrcykge1xuICAgICAgICBjb21waWxlcnMgPSB0cnVlO1xuICAgICAgICBuZXR3b3JrcyA9IGRldi5uZXR3b3JrcztcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29tcGlsZXJzLFxuICAgICAgICBuZXR3b3JrczogbmV0d29ya3MgfHwgW11cbiAgICB9O1xufVxuXG4iXX0= -------------------------------------------------------------------------------- /__tests__/cli.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2019 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | 16 | import {handleCommandLine} from "../src/cli/cli"; 17 | import {Dev} from "../src/dev"; 18 | 19 | jest.setTimeout(60_000); 20 | 21 | async function cmd(...args) { 22 | const argv = [process.argv0, 'index', ...args]; 23 | const dev = new Dev(); 24 | let out = ''; 25 | const saveConsoleLog = console.log; 26 | console.log = (...args) => { 27 | out = `${out}${args.join('')}\n`; 28 | } 29 | await handleCommandLine(dev, argv); 30 | console.log = saveConsoleLog; 31 | return out; 32 | } 33 | 34 | test.skip('Masterchain addr', async () => { 35 | // await cmd('a', '-1:0b0cb5e0bc0bc0baa3ea45a37d14dee1b1a24befa40c7be54aeaf8fcc7438b5c'); 36 | 37 | const hexToAddresses = await cmd('a', '-1:5555555555555555555555555555555555555555555555555555555555555555'); 38 | const bounceToHex = await cmd('a', 'Uf9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVeGi'); 39 | console.log('>>>', { 40 | hexToAddresses, 41 | bounceToHex 42 | }); 43 | }); 44 | 45 | 46 | async function expectError(code: number, source: string, message?: string, f) { 47 | try { 48 | await f(); 49 | fail(`Expected error with code:${code} source: ${source}`); 50 | } catch (error) { 51 | expect({ code: error.code, source: error.source }).toEqual({ code, source }); 52 | if (message) 53 | expect(error.message).toMatch(message); 54 | } 55 | } 56 | 57 | 58 | test('Should convert diff address format', async () => { 59 | const hexToAddresses = await cmd('a', '-1:5555555555555555555555555555555555555555555555555555555555555555'); 60 | expect(hexToAddresses).toMatch("✓ hex = -1:5555555555555555555555555555555555555555555555555555555555555555"); 61 | expect(hexToAddresses).toMatch("main = Uf9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVeGi"); 62 | expect(hexToAddresses).toMatch("main url = Uf9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVeGi"); 63 | expect(hexToAddresses).toMatch("main bounce = Ef9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVbxn"); 64 | expect(hexToAddresses).toMatch("main bounce url = Ef9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVbxn") 65 | expect(hexToAddresses).toMatch("test = 0f9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVoo"); 66 | expect(hexToAddresses).toMatch("test url = 0f9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVoo"); 67 | expect(hexToAddresses).toMatch("test bounce = kf9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQft"); 68 | expect(hexToAddresses).toMatch("test bounce url = kf9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQft"); 69 | 70 | 71 | const bounceToHex = await cmd('a', 'Uf9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVeGi'); 72 | expect(bounceToHex).toMatch("hex = -1:5555555555555555555555555555555555555555555555555555555555555555"); 73 | expect(bounceToHex).toMatch("✓ main = Uf9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVeGi"); 74 | expect(bounceToHex).toMatch("✓ main url = Uf9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVeGi"); 75 | 76 | const bounceToHexWithSlash = await cmd('addr', 'EQA9uzKPV4JLKXPoQM2ddKOAfo99hcO_NCBsHG-1Q-QE2ah8'); 77 | expect(bounceToHexWithSlash).toMatch("main bounce = EQA9uzKPV4JLKXPoQM2ddKOAfo99hcO/NCBsHG+1Q+QE2ah8"); 78 | expect(bounceToHexWithSlash).toMatch("✓ main bounce url = EQA9uzKPV4JLKXPoQM2ddKOAfo99hcO_NCBsHG-1Q-QE2ah8"); 79 | 80 | 81 | const otherWorkchainId = await cmd('a', '0:0000000000000000000000000000000000000000000000000000000000000000'); 82 | expect(otherWorkchainId).toMatch("✓ hex = 0:0000000000000000000000000000000000000000000000000000000000000000"); 83 | 84 | const minWorkchainId = await cmd('a', '-128:0000000000000000000000000000000000000000000000000000000000000000'); 85 | expect(minWorkchainId).toMatch("✓ hex = -128:0000000000000000000000000000000000000000000000000000000000000000"); 86 | 87 | const maxWorkchainId = await cmd('a', '127:0000000000000000000000000000000000000000000000000000000000000000'); 88 | expect(maxWorkchainId).toMatch("✓ hex = 127:0000000000000000000000000000000000000000000000000000000000000000"); 89 | 90 | await expectError(2004, 'client', 'Invalid address [Non-std address]: 128:0000000000000000000000000000000000000000000000000000000000000000', async () => { 91 | await cmd('a', '128:0000000000000000000000000000000000000000000000000000000000000000'); 92 | }); 93 | 94 | await expectError(2004, 'client', 'Invalid address [Non-std address]: -129:0000000000000000000000000000000000000000000000000000000000000000', async () => { 95 | await cmd('a', '-129:0000000000000000000000000000000000000000000000000000000000000000'); 96 | }); 97 | 98 | await expectError(2004, 'client', 'Invalid address [fatal error]:', async () => { 99 | await cmd('a', 'wrong'); 100 | }); 101 | 102 | await expectError(2004, 'client', 'Invalid address [Invalid argument: account address should be 256 bits long in workchain 0]', async () => { 103 | await cmd('a', '00000000000000000000000'); 104 | }); 105 | 106 | await expectError(2004, 'client', 'Invalid address [Invalid argument: workchain_id is not correct number: invalid digit found in string]', async () => { 107 | await cmd('a', 'ff:0000000000000000000000000000000000000000000000000000000000000000'); 108 | }); 109 | }); 110 | -------------------------------------------------------------------------------- /src/compilers/client-code.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | 16 | // @flow 17 | 18 | import { parseFileArg } from "../utils/utils"; 19 | import Handlebars from 'handlebars'; 20 | import { parseSolidityFileArg } from "./solidity"; 21 | 22 | const path = require('path'); 23 | const fs = require('fs'); 24 | 25 | type Template = { 26 | build: any 27 | } 28 | 29 | Handlebars.registerHelper('LB', () => '{'); 30 | Handlebars.registerHelper('RB', () => '}'); 31 | 32 | function compileTemplate(...pathItems: string[]): Template { 33 | const templatePath = path.resolve(__dirname, '..', '..', ...pathItems); 34 | const templateText = fs.readFileSync(templatePath, { encoding: 'utf8' }); 35 | return { 36 | build: Handlebars.compile(templateText, { 37 | noEscape: true, 38 | }) 39 | }; 40 | } 41 | 42 | async function applyTemplate(template: Template, context: any): Promise { 43 | return template.build(context); 44 | } 45 | 46 | const jsContractTemplate = compileTemplate('js-templates', 'contract.js.hbs'); 47 | 48 | export const ClientCodeLevel = { 49 | none: 'none', 50 | run: 'run', 51 | deploy: 'deploy' 52 | }; 53 | 54 | export type ClientCodeLevelType = $Keys; 55 | 56 | export type ClientCodeLanguageType = string; 57 | 58 | export const JSModule = { 59 | node: 'node', 60 | nodeNoDefault: 'nodeNoDefault', 61 | es: 'es', 62 | esNoDefault: 'esNoDefault', 63 | }; 64 | 65 | export type JSModuleType = $Keys; 66 | 67 | export type ClientCodeOptions = { 68 | clientLanguages: ClientCodeLanguageType[], 69 | clientLevel: ClientCodeLevelType, 70 | jsModule: JSModuleType, 71 | }; 72 | 73 | export interface ClientCodeLanguage { 74 | name: string, 75 | shortName: string, 76 | generate: (files: string[], options: ClientCodeOptions) => Promise 77 | } 78 | 79 | export class ClientCode { 80 | static languages: { [string]: ClientCodeLanguage } = {}; 81 | 82 | static register(language: ClientCodeLanguage) { 83 | ClientCode.languages[language.shortName.toLowerCase()] = language; 84 | } 85 | 86 | static async generate(files: string[], options: ClientCodeOptions) { 87 | for (const name of options.clientLanguages) { 88 | const language = ClientCode.languages[name.toLocaleLowerCase()]; 89 | if (!language) { 90 | throw Error(`Unknown client code language: ${name}`); 91 | } 92 | await language.generate(files, options); 93 | } 94 | } 95 | } 96 | 97 | const JsClientCode = { 98 | name: 'JavaScript', 99 | shortName: 'js', 100 | getTemplateContext(fileArg: string, options: ClientCodeOptions): any { 101 | const file = parseSolidityFileArg(fileArg, false); 102 | const { dir, name } = file; 103 | const readText = (name: string, encoding: 'utf8' | 'base64'): string => { 104 | if (!fs.existsSync(dir(name))) { 105 | throw new Error(`File not exists: ${name}`); 106 | } 107 | return fs.readFileSync(dir(name)).toString(encoding); 108 | }; 109 | 110 | const imageBase64 = options.clientLevel === ClientCodeLevel.deploy 111 | ? readText(name.tvc, 'base64') 112 | : ''; 113 | const abiJson = readText(name.abi, 'utf8').trimRight(); 114 | const abi = { 115 | functions: [], 116 | data: [], 117 | ...JSON.parse(abiJson) 118 | }; 119 | 120 | const className = `${name.base[0].toUpperCase()}${name.base.substr(1)}Contract`; 121 | const isDeploy = (options.clientLevel || 'deploy') === 'deploy'; 122 | 123 | const varContext = (v) => { 124 | const jsType = { 125 | address: 'string', 126 | 'address[]': 'string[]', 127 | uint256: 'string', 128 | uint32: 'number', 129 | uint16: 'number', 130 | uint8: 'number', 131 | 'uint256[]': 'string[]', 132 | 'uint32[]': 'number[]', 133 | 'uint16[]': 'number[]', 134 | 'uint8[]': 'number[]', 135 | }[v.type] || v.type; 136 | return { 137 | ...v, 138 | jsType, 139 | isSameJsType: jsType === v.type, 140 | } 141 | }; 142 | 143 | const funContext = (f) => { 144 | return { 145 | ...f, 146 | hasData: false, 147 | hasInputsAndData: false, 148 | hasInputs: f.inputs.length > 0, 149 | hasOutputs: f.outputs.length > 0, 150 | inputs: f.inputs.map(varContext), 151 | outputs: f.outputs.map(varContext), 152 | } 153 | }; 154 | 155 | const constructor = funContext(abi.functions.find(x => x.name === 'constructor') || { 156 | name: 'constructor', 157 | inputs: [], 158 | outputs: [], 159 | data: [], 160 | }); 161 | constructor.hasData = abi.data.length > 0; 162 | constructor.hasInputsAndData = constructor.hasInputs && constructor.hasData; 163 | constructor.data = abi.data.map(varContext); 164 | 165 | const functions = abi.functions.filter(x => x.name !== 'constructor').map(funContext); 166 | return { 167 | imageBase64, 168 | abiJson, 169 | abi, 170 | className, 171 | isDeploy, 172 | constructor, 173 | functions, 174 | jsModuleNode: options.jsModule === JSModule.node || options.jsModule === JSModule.nodeNoDefault, 175 | jsModuleNodeDefault: options.jsModule === JSModule.node, 176 | jsModuleEs: options.jsModule === JSModule.es || options.jsModule === JSModule.esNoDefault, 177 | jsModuleEsDefault: options.jsModule === JSModule.es, 178 | }; 179 | }, 180 | async generate(files: string[], options: ClientCodeOptions) { 181 | for (const file of files) { 182 | const { dir, base } = parseFileArg(file, '.sol', false); 183 | const js = await applyTemplate(jsContractTemplate, JsClientCode.getTemplateContext(file, options)); 184 | fs.writeFileSync(dir(`${base}Contract.js`), js, { encoding: 'utf8' }); 185 | } 186 | } 187 | }; 188 | 189 | ClientCode.register(JsClientCode); 190 | -------------------------------------------------------------------------------- /src/utils/utils.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | // @flow 16 | import { texts } from './texts'; 17 | 18 | const fs = require('fs'); 19 | const os = require('os'); 20 | const path = require('path'); 21 | const { spawn } = require('child_process'); 22 | const version = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '..', 'package.json')).toString()).version; 23 | 24 | function showUsage(usage: string) { 25 | console.log(texts.usageHeader(version)); 26 | console.log(usage); 27 | } 28 | 29 | const spawnEnv = { 30 | ...process.env, 31 | }; 32 | 33 | function run(name: string, ...args: string[]): Promise { 34 | return new Promise((resolve, reject) => { 35 | try { 36 | const spawned = spawn(name, args, { env: spawnEnv }); 37 | const errors = []; 38 | const output = []; 39 | 40 | spawned.stdout.on('data', function (data) { 41 | output.push(data.toString()); 42 | }); 43 | 44 | spawned.stderr.on('data', (data) => { 45 | errors.push(data.toString()); 46 | }); 47 | 48 | spawned.on('error', (err) => { 49 | reject(err); 50 | }); 51 | 52 | spawned.on('close', (code) => { 53 | if (code === 0) { 54 | resolve(output.join('')); 55 | } else { 56 | reject(errors.join('')); 57 | } 58 | }); 59 | } catch (error) { 60 | reject(error); 61 | } 62 | }); 63 | } 64 | 65 | function versionToNumber(s: string): number { 66 | const parts = `${s || ''}`.split('.').map(x => Number.parseInt(x)).slice(0, 3); 67 | while (parts.length < 3) { 68 | parts.push(0); 69 | } 70 | return parts[0] * 1000000 + parts[1] * 1000 + parts[2]; 71 | } 72 | 73 | function forceRmDir(dir: string) { 74 | fs.readdirSync(dir).forEach((item) => { 75 | const itemPath = path.join(dir, item); 76 | const stat = fs.statSync(itemPath); 77 | 78 | if (itemPath === "." || itemPath === "..") { 79 | } else if (stat.isDirectory()) { 80 | forceRmDir(itemPath); 81 | } else { 82 | fs.unlinkSync(itemPath); 83 | } 84 | }); 85 | fs.rmdirSync(dir); 86 | } 87 | 88 | function ensureCleanDirectory(path: string) { 89 | if (fs.existsSync(path)) { 90 | forceRmDir(path); 91 | } 92 | fs.mkdirSync(path, ({ recursive: true }: any)); 93 | } 94 | 95 | export type PathJoin = (...items: string[]) => string; 96 | 97 | function join(base: string, item: string, separator: string): string { 98 | const baseWithSep = base.endsWith(separator); 99 | const itemWithSep = item.startsWith(separator); 100 | if (baseWithSep && itemWithSep) { 101 | return `${base}${item.substr(1)}`; 102 | } 103 | if (!baseWithSep && !itemWithSep) { 104 | return `${base}/${item}`; 105 | } 106 | return `${base}${item}`; 107 | } 108 | 109 | function bindPathJoinTo(base: string, separator?: string): PathJoin { 110 | if (separator) { 111 | const sep = separator; 112 | return (...items: string[]): string => { 113 | let path = base; 114 | items.forEach(x => path = join(path, x, sep)); 115 | return path; 116 | } 117 | } 118 | return (...items: string[]): string => { 119 | return items.length > 0 ? path.join(base, ...items) : base; 120 | } 121 | } 122 | 123 | 124 | function inputLine(): Promise { 125 | return new Promise((resolve) => { 126 | const standard_input = process.stdin; 127 | standard_input.setEncoding('utf-8'); 128 | standard_input.once('data', function (data) { 129 | resolve(`${data}`.trim()); 130 | }); 131 | }); 132 | } 133 | 134 | function breakWords(s: string): string { 135 | const words = s.split(' '); 136 | let result = ''; 137 | let line = ''; 138 | words.forEach((w) => { 139 | if (line.length + w.length > 80) { 140 | if (result !== '') { 141 | result += '\n'; 142 | } 143 | result += line; 144 | line = ''; 145 | } 146 | if (line !== '') { 147 | line += ' '; 148 | } 149 | line += w; 150 | }); 151 | if (line !== '') { 152 | if (result !== '') { 153 | result += '\n'; 154 | } 155 | result += line; 156 | } 157 | return result; 158 | } 159 | 160 | 161 | const https = require('https'); 162 | 163 | function httpsGetJson(url: string): Promise { 164 | return new Promise<*[]>((resolve, reject) => { 165 | const tryUrl = (url) => { 166 | https.get(url, function (res) { 167 | let body = ''; 168 | 169 | res.on('data', function (chunk) { 170 | body += chunk; 171 | }); 172 | 173 | res.on('end', function () { 174 | if (res.statusCode === 301) { 175 | const redirectUrl = res.headers['location']; 176 | tryUrl(redirectUrl); 177 | return; 178 | } 179 | const response = JSON.parse(body); 180 | resolve(response); 181 | }); 182 | }).on('error', (error) => { 183 | reject(error); 184 | }); 185 | }; 186 | tryUrl(url); 187 | }) 188 | } 189 | 190 | function toIdentifier(s: string): string { 191 | let identifier = ''; 192 | for (let i = 0; i < s.length; i += 1) { 193 | const c = s[i]; 194 | const isLetter = c.toLowerCase() !== c.toUpperCase(); 195 | const isDigit = !isLetter && '0123456789'.includes(c); 196 | if (isLetter || isDigit) { 197 | identifier += c; 198 | } 199 | } 200 | return identifier; 201 | } 202 | 203 | const userIdentifier = toIdentifier(os.userInfo().username).toLowerCase(); 204 | const tonlabsHomePath = bindPathJoinTo(path.join(os.homedir(), '.tonlabs')); 205 | 206 | let _progressLine: string = ''; 207 | 208 | function progressLine(line: string) { 209 | process.stdout.write(`\r${line}`); 210 | const extra = _progressLine.length - line.length; 211 | if (extra > 0) { 212 | process.stdout.write(' '.repeat(extra) + '\b'.repeat(extra)); 213 | } 214 | _progressLine = line; 215 | } 216 | 217 | function progress(info: string) { 218 | progressLine(`${info}...`); 219 | } 220 | 221 | function progressDone() { 222 | console.log(' ✓'); 223 | _progressLine = ''; 224 | } 225 | 226 | export type FileArg = { 227 | dir: PathJoin, 228 | base: string, 229 | name: string 230 | } 231 | 232 | function parseFileArg(fileArg: string, ext: string, fileMustExists: boolean): FileArg { 233 | if (os.platform() === 'darwin' && fileArg.startsWith('~/')) { 234 | fileArg = path.join(os.homedir(), fileArg.substr(2)); 235 | } 236 | const filePath = path.resolve(fileArg); 237 | const dir = bindPathJoinTo(path.dirname(filePath)); 238 | const base = path.basename(filePath, ext); 239 | const name = base.includes('.') ? base : `${base}${ext}`; 240 | const result = { 241 | dir, 242 | base, 243 | name 244 | }; 245 | if (fileMustExists && !fs.existsSync(result.dir(name))) { 246 | console.error(texts.sourceFileNotFound(name)); 247 | process.exit(1); 248 | } 249 | return result; 250 | } 251 | 252 | 253 | 254 | export { 255 | version, 256 | showUsage, 257 | run, 258 | versionToNumber, 259 | forceRmDir, 260 | ensureCleanDirectory, 261 | bindPathJoinTo, 262 | inputLine, 263 | breakWords, 264 | httpsGetJson, 265 | toIdentifier, 266 | userIdentifier, 267 | tonlabsHomePath, 268 | progress, 269 | progressLine, 270 | progressDone, 271 | parseFileArg, 272 | } 273 | -------------------------------------------------------------------------------- /dist/compilers/compilers.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.Compilers = void 0; 7 | 8 | var _docker = require("../utils/docker"); 9 | 10 | var _utils = require("../utils/utils"); 11 | 12 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } 13 | 14 | class Compilers { 15 | constructor(config) { 16 | _defineProperty(this, "version", void 0); 17 | 18 | _defineProperty(this, "requiredImage", void 0); 19 | 20 | _defineProperty(this, "containerName", void 0); 21 | 22 | _defineProperty(this, "mountDestination", void 0); 23 | 24 | this.setConfig(config); 25 | } 26 | 27 | setConfig(config) { 28 | this.version = config.version; 29 | this.requiredImage = `${Compilers.imagePrefix}:${config.version}`; 30 | this.containerName = `${Compilers.containerPrefix}-${_utils.userIdentifier}`; 31 | this.mountDestination = '/projects'; 32 | } 33 | 34 | getConfig() { 35 | return { 36 | version: this.version 37 | }; 38 | } 39 | 40 | async createContainer(docker) { 41 | throw new Error('Internal error: invalid call to Compilers.createContainer'); 42 | } 43 | 44 | async createContainerMountedTo(hostPath, docker) { 45 | await docker.ensureImage(this.requiredImage); 46 | const existing = await docker.getContainerInfos(); 47 | let name = ''; 48 | let index = 0; 49 | 50 | do { 51 | name = `${this.containerName}${index > 0 ? `-${index}` : ''}`; 52 | index += 1; 53 | } while (existing.find(x => _docker.DevDocker.hasName(x, name))); 54 | 55 | docker.dropCache(); 56 | return docker.client.createContainer({ 57 | name, 58 | interactive: true, 59 | Image: this.requiredImage, 60 | Tty: true, 61 | Env: ['USER_AGREEMENT=yes'], 62 | HostConfig: { 63 | Mounts: [{ 64 | Type: 'bind', 65 | Source: hostPath, 66 | Target: this.mountDestination 67 | }] 68 | } 69 | }); 70 | } 71 | 72 | } 73 | 74 | exports.Compilers = Compilers; 75 | 76 | _defineProperty(Compilers, "imagePrefix", 'tonlabs/compilers'); 77 | 78 | _defineProperty(Compilers, "containerPrefix", 'tonlabs-compilers'); 79 | 80 | _defineProperty(Compilers, "defaultConfig", Object.freeze({ 81 | version: 'latest' 82 | })); 83 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21waWxlcnMvY29tcGlsZXJzLmpzIl0sIm5hbWVzIjpbIkNvbXBpbGVycyIsImNvbnN0cnVjdG9yIiwiY29uZmlnIiwic2V0Q29uZmlnIiwidmVyc2lvbiIsInJlcXVpcmVkSW1hZ2UiLCJpbWFnZVByZWZpeCIsImNvbnRhaW5lck5hbWUiLCJjb250YWluZXJQcmVmaXgiLCJ1c2VySWRlbnRpZmllciIsIm1vdW50RGVzdGluYXRpb24iLCJnZXRDb25maWciLCJjcmVhdGVDb250YWluZXIiLCJkb2NrZXIiLCJFcnJvciIsImNyZWF0ZUNvbnRhaW5lck1vdW50ZWRUbyIsImhvc3RQYXRoIiwiZW5zdXJlSW1hZ2UiLCJleGlzdGluZyIsImdldENvbnRhaW5lckluZm9zIiwibmFtZSIsImluZGV4IiwiZmluZCIsIngiLCJEZXZEb2NrZXIiLCJoYXNOYW1lIiwiZHJvcENhY2hlIiwiY2xpZW50IiwiaW50ZXJhY3RpdmUiLCJJbWFnZSIsIlR0eSIsIkVudiIsIkhvc3RDb25maWciLCJNb3VudHMiLCJUeXBlIiwiU291cmNlIiwiVGFyZ2V0IiwiT2JqZWN0IiwiZnJlZXplIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBZ0JBOztBQUNBOzs7O0FBT08sTUFBTUEsU0FBTixDQUF3QztBQVkzQ0MsRUFBQUEsV0FBVyxDQUFDQyxNQUFELEVBQTBCO0FBQUE7O0FBQUE7O0FBQUE7O0FBQUE7O0FBQ2pDLFNBQUtDLFNBQUwsQ0FBZUQsTUFBZjtBQUNIOztBQUVEQyxFQUFBQSxTQUFTLENBQUNELE1BQUQsRUFBMEI7QUFDL0IsU0FBS0UsT0FBTCxHQUFlRixNQUFNLENBQUNFLE9BQXRCO0FBQ0EsU0FBS0MsYUFBTCxHQUFzQixHQUFFTCxTQUFTLENBQUNNLFdBQVksSUFBR0osTUFBTSxDQUFDRSxPQUFRLEVBQWhFO0FBQ0EsU0FBS0csYUFBTCxHQUFzQixHQUFFUCxTQUFTLENBQUNRLGVBQWdCLElBQUdDLHFCQUFlLEVBQXBFO0FBQ0EsU0FBS0MsZ0JBQUwsR0FBd0IsV0FBeEI7QUFDSDs7QUFFREMsRUFBQUEsU0FBUyxHQUFvQjtBQUN6QixXQUFPO0FBQ0hQLE1BQUFBLE9BQU8sRUFBRSxLQUFLQTtBQURYLEtBQVA7QUFHSDs7QUFFRCxRQUFNUSxlQUFOLENBQXNCQyxNQUF0QixFQUFtRTtBQUMvRCxVQUFNLElBQUlDLEtBQUosQ0FBVSwyREFBVixDQUFOO0FBQ0g7O0FBRUQsUUFBTUMsd0JBQU4sQ0FBK0JDLFFBQS9CLEVBQWlESCxNQUFqRCxFQUE4RjtBQUMxRixVQUFNQSxNQUFNLENBQUNJLFdBQVAsQ0FBbUIsS0FBS1osYUFBeEIsQ0FBTjtBQUNBLFVBQU1hLFFBQVEsR0FBRyxNQUFNTCxNQUFNLENBQUNNLGlCQUFQLEVBQXZCO0FBQ0EsUUFBSUMsSUFBSSxHQUFHLEVBQVg7QUFDQSxRQUFJQyxLQUFLLEdBQUcsQ0FBWjs7QUFDQSxPQUFHO0FBQ0NELE1BQUFBLElBQUksR0FBSSxHQUFFLEtBQUtiLGFBQWMsR0FBRWMsS0FBSyxHQUFHLENBQVIsR0FBYSxJQUFHQSxLQUFNLEVBQXRCLEdBQTBCLEVBQUcsRUFBNUQ7QUFDQUEsTUFBQUEsS0FBSyxJQUFJLENBQVQ7QUFDSCxLQUhELFFBR1NILFFBQVEsQ0FBQ0ksSUFBVCxDQUFjQyxDQUFDLElBQUlDLGtCQUFVQyxPQUFWLENBQWtCRixDQUFsQixFQUFxQkgsSUFBckIsQ0FBbkIsQ0FIVDs7QUFJQVAsSUFBQUEsTUFBTSxDQUFDYSxTQUFQO0FBQ0EsV0FBT2IsTUFBTSxDQUFDYyxNQUFQLENBQWNmLGVBQWQsQ0FBOEI7QUFDakNRLE1BQUFBLElBRGlDO0FBRWpDUSxNQUFBQSxXQUFXLEVBQUUsSUFGb0I7QUFHakNDLE1BQUFBLEtBQUssRUFBRSxLQUFLeEIsYUFIcUI7QUFJakN5QixNQUFBQSxHQUFHLEVBQUUsSUFKNEI7QUFLakNDLE1BQUFBLEdBQUcsRUFBRSxDQUFDLG9CQUFELENBTDRCO0FBTWpDQyxNQUFBQSxVQUFVLEVBQUU7QUFDUkMsUUFBQUEsTUFBTSxFQUFFLENBQ0o7QUFDSUMsVUFBQUEsSUFBSSxFQUFFLE1BRFY7QUFFSUMsVUFBQUEsTUFBTSxFQUFFbkIsUUFGWjtBQUdJb0IsVUFBQUEsTUFBTSxFQUFFLEtBQUsxQjtBQUhqQixTQURJO0FBREE7QUFOcUIsS0FBOUIsQ0FBUDtBQWdCSDs7QUEzRDBDOzs7O2dCQUFsQ1YsUyxpQkFDWSxtQjs7Z0JBRFpBLFMscUJBRWdCLG1COztnQkFGaEJBLFMsbUJBRytCcUMsTUFBTSxDQUFDQyxNQUFQLENBQWM7QUFDbERsQyxFQUFBQSxPQUFPLEVBQUU7QUFEeUMsQ0FBZCxDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAyMDE4LTIwMjAgVE9OIERFViBTT0xVVElPTlMgTFRELlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBTT0ZUV0FSRSBFVkFMVUFUSU9OIExpY2Vuc2UgKHRoZSBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZVxuICogdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlXG4gKiBMaWNlbnNlIGF0OiBodHRwczovL3d3dy50b24uZGV2L2xpY2Vuc2VzXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBUT04gREVWIHNvZnR3YXJlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuLy8gQGZsb3dcbmltcG9ydCB0eXBlIHsgQ29udGFpbmVyRGVmLCBEb2NrZXJDb250YWluZXIgfSBmcm9tIFwiLi4vdXRpbHMvZG9ja2VyXCI7XG5pbXBvcnQgeyBEZXZEb2NrZXIgfSBmcm9tIFwiLi4vdXRpbHMvZG9ja2VyXCI7XG5pbXBvcnQgeyB1c2VySWRlbnRpZmllciB9IGZyb20gXCIuLi91dGlscy91dGlsc1wiO1xuXG5leHBvcnQgdHlwZSBDb21waWxlcnNDb25maWcgPSB7XG4gICAgdmVyc2lvbjogc3RyaW5nLFxufVxuXG5cbmV4cG9ydCBjbGFzcyBDb21waWxlcnMgaW1wbGVtZW50cyBDb250YWluZXJEZWYge1xuICAgIHN0YXRpYyBpbWFnZVByZWZpeCA9ICd0b25sYWJzL2NvbXBpbGVycyc7XG4gICAgc3RhdGljIGNvbnRhaW5lclByZWZpeCA9ICd0b25sYWJzLWNvbXBpbGVycyc7XG4gICAgc3RhdGljIGRlZmF1bHRDb25maWc6IENvbXBpbGVyc0NvbmZpZyA9IE9iamVjdC5mcmVlemUoe1xuICAgICAgICB2ZXJzaW9uOiAnbGF0ZXN0J1xuICAgIH0pO1xuXG4gICAgdmVyc2lvbjogc3RyaW5nO1xuICAgIHJlcXVpcmVkSW1hZ2U6IHN0cmluZztcbiAgICBjb250YWluZXJOYW1lOiBzdHJpbmc7XG4gICAgbW91bnREZXN0aW5hdGlvbjogc3RyaW5nO1xuXG4gICAgY29uc3RydWN0b3IoY29uZmlnOiBDb21waWxlcnNDb25maWcpIHtcbiAgICAgICAgdGhpcy5zZXRDb25maWcoY29uZmlnKTtcbiAgICB9XG5cbiAgICBzZXRDb25maWcoY29uZmlnOiBDb21waWxlcnNDb25maWcpIHtcbiAgICAgICAgdGhpcy52ZXJzaW9uID0gY29uZmlnLnZlcnNpb247XG4gICAgICAgIHRoaXMucmVxdWlyZWRJbWFnZSA9IGAke0NvbXBpbGVycy5pbWFnZVByZWZpeH06JHtjb25maWcudmVyc2lvbn1gO1xuICAgICAgICB0aGlzLmNvbnRhaW5lck5hbWUgPSBgJHtDb21waWxlcnMuY29udGFpbmVyUHJlZml4fS0ke3VzZXJJZGVudGlmaWVyfWA7XG4gICAgICAgIHRoaXMubW91bnREZXN0aW5hdGlvbiA9ICcvcHJvamVjdHMnO1xuICAgIH1cblxuICAgIGdldENvbmZpZygpOiBDb21waWxlcnNDb25maWcge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmVyc2lvbjogdGhpcy52ZXJzaW9uLFxuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgY3JlYXRlQ29udGFpbmVyKGRvY2tlcjogRGV2RG9ja2VyKTogUHJvbWlzZTxEb2NrZXJDb250YWluZXI+IHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnRlcm5hbCBlcnJvcjogaW52YWxpZCBjYWxsIHRvIENvbXBpbGVycy5jcmVhdGVDb250YWluZXInKTtcbiAgICB9XG5cbiAgICBhc3luYyBjcmVhdGVDb250YWluZXJNb3VudGVkVG8oaG9zdFBhdGg6IHN0cmluZywgZG9ja2VyOiBEZXZEb2NrZXIpOiBQcm9taXNlPERvY2tlckNvbnRhaW5lcj4ge1xuICAgICAgICBhd2FpdCBkb2NrZXIuZW5zdXJlSW1hZ2UodGhpcy5yZXF1aXJlZEltYWdlKTtcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBkb2NrZXIuZ2V0Q29udGFpbmVySW5mb3MoKTtcbiAgICAgICAgbGV0IG5hbWUgPSAnJztcbiAgICAgICAgbGV0IGluZGV4ID0gMDtcbiAgICAgICAgZG8ge1xuICAgICAgICAgICAgbmFtZSA9IGAke3RoaXMuY29udGFpbmVyTmFtZX0ke2luZGV4ID4gMCA/IGAtJHtpbmRleH1gIDogJyd9YDtcbiAgICAgICAgICAgIGluZGV4ICs9IDE7XG4gICAgICAgIH0gd2hpbGUgKGV4aXN0aW5nLmZpbmQoeCA9PiBEZXZEb2NrZXIuaGFzTmFtZSh4LCBuYW1lKSkpO1xuICAgICAgICBkb2NrZXIuZHJvcENhY2hlKCk7XG4gICAgICAgIHJldHVybiBkb2NrZXIuY2xpZW50LmNyZWF0ZUNvbnRhaW5lcih7XG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgaW50ZXJhY3RpdmU6IHRydWUsXG4gICAgICAgICAgICBJbWFnZTogdGhpcy5yZXF1aXJlZEltYWdlLFxuICAgICAgICAgICAgVHR5OiB0cnVlLFxuICAgICAgICAgICAgRW52OiBbJ1VTRVJfQUdSRUVNRU5UPXllcyddLFxuICAgICAgICAgICAgSG9zdENvbmZpZzoge1xuICAgICAgICAgICAgICAgIE1vdW50czogW1xuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBUeXBlOiAnYmluZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBTb3VyY2U6IGhvc3RQYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgVGFyZ2V0OiB0aGlzLm1vdW50RGVzdGluYXRpb24sXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiJdfQ== -------------------------------------------------------------------------------- /dist/server/server.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.web = web; 7 | exports.TONDevWebConsole = void 0; 8 | 9 | var _dev = require("../dev"); 10 | 11 | var _utils = require("../utils/utils"); 12 | 13 | var _handlebars = _interopRequireDefault(require("handlebars")); 14 | 15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 16 | 17 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } 18 | 19 | const express = require('express'); 20 | 21 | const cors = require('cors'); 22 | 23 | const path = require('path'); 24 | 25 | const fs = require('fs'); 26 | 27 | function applyTemplate(name, context) { 28 | const templatePath = path.resolve(__dirname, '..', '..', 'src', 'server', 'templates', `${name}.hbs`); 29 | const templateText = fs.readFileSync(templatePath, { 30 | encoding: 'utf8' 31 | }); 32 | 33 | const template = _handlebars.default.compile(templateText, { 34 | noEscape: true 35 | }); 36 | 37 | return template(context); 38 | } 39 | 40 | class TONDevWebConsole { 41 | constructor(dev, options) { 42 | _defineProperty(this, "dev", void 0); 43 | 44 | _defineProperty(this, "options", void 0); 45 | 46 | this.dev = dev; 47 | this.options = options; 48 | } 49 | 50 | start() { 51 | const app = express(); 52 | app.use(express.json()); 53 | app.use(cors()); 54 | app.get('/', this.main.bind(this)); 55 | app.listen({ 56 | port: this.options.port 57 | }, () => { 58 | const uri = `http://localhost:${this.options.port}`; 59 | console.debug(`TON Dev Web Console started on ${uri}`); 60 | }); 61 | } 62 | 63 | async main(req, res) { 64 | try { 65 | await res.send(applyTemplate('main', this.dev)); 66 | res.end(); 67 | } catch (error) { 68 | console.log('[Web Console] request failed', error); 69 | await res.json({ 70 | jsonrpc: '2.0', 71 | id: 1, 72 | error: { 73 | code: Number.parseInt(error && error.code) || 1, 74 | message: error.message || error.toString(), 75 | data: error 76 | } 77 | }); 78 | } 79 | } 80 | 81 | } 82 | 83 | exports.TONDevWebConsole = TONDevWebConsole; 84 | 85 | async function web(dev, options) { 86 | const server = new TONDevWebConsole(dev, options); 87 | server.start(); 88 | return (0, _utils.inputLine)(); 89 | } 90 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2ZXIvc2VydmVyLmpzIl0sIm5hbWVzIjpbImV4cHJlc3MiLCJyZXF1aXJlIiwiY29ycyIsInBhdGgiLCJmcyIsImFwcGx5VGVtcGxhdGUiLCJuYW1lIiwiY29udGV4dCIsInRlbXBsYXRlUGF0aCIsInJlc29sdmUiLCJfX2Rpcm5hbWUiLCJ0ZW1wbGF0ZVRleHQiLCJyZWFkRmlsZVN5bmMiLCJlbmNvZGluZyIsInRlbXBsYXRlIiwiSGFuZGxlYmFycyIsImNvbXBpbGUiLCJub0VzY2FwZSIsIlRPTkRldldlYkNvbnNvbGUiLCJjb25zdHJ1Y3RvciIsImRldiIsIm9wdGlvbnMiLCJzdGFydCIsImFwcCIsInVzZSIsImpzb24iLCJnZXQiLCJtYWluIiwiYmluZCIsImxpc3RlbiIsInBvcnQiLCJ1cmkiLCJjb25zb2xlIiwiZGVidWciLCJyZXEiLCJyZXMiLCJzZW5kIiwiZW5kIiwiZXJyb3IiLCJsb2ciLCJqc29ucnBjIiwiaWQiLCJjb2RlIiwiTnVtYmVyIiwicGFyc2VJbnQiLCJtZXNzYWdlIiwidG9TdHJpbmciLCJkYXRhIiwid2ViIiwic2VydmVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQWtCQTs7QUFDQTs7QUFJQTs7Ozs7O0FBRkEsTUFBTUEsT0FBTyxHQUFHQyxPQUFPLENBQUMsU0FBRCxDQUF2Qjs7QUFDQSxNQUFNQyxJQUFJLEdBQUdELE9BQU8sQ0FBQyxNQUFELENBQXBCOztBQUdBLE1BQU1FLElBQUksR0FBR0YsT0FBTyxDQUFDLE1BQUQsQ0FBcEI7O0FBQ0EsTUFBTUcsRUFBRSxHQUFHSCxPQUFPLENBQUMsSUFBRCxDQUFsQjs7QUFFQSxTQUFTSSxhQUFULENBQXVCQyxJQUF2QixFQUFxQ0MsT0FBckMsRUFBb0U7QUFDaEUsUUFBTUMsWUFBWSxHQUFHTCxJQUFJLENBQUNNLE9BQUwsQ0FBYUMsU0FBYixFQUF3QixJQUF4QixFQUE4QixJQUE5QixFQUFvQyxLQUFwQyxFQUEyQyxRQUEzQyxFQUFxRCxXQUFyRCxFQUFtRSxHQUFFSixJQUFLLE1BQTFFLENBQXJCO0FBQ0EsUUFBTUssWUFBWSxHQUFHUCxFQUFFLENBQUNRLFlBQUgsQ0FBZ0JKLFlBQWhCLEVBQThCO0FBQUVLLElBQUFBLFFBQVEsRUFBRTtBQUFaLEdBQTlCLENBQXJCOztBQUNBLFFBQU1DLFFBQVEsR0FBR0Msb0JBQVdDLE9BQVgsQ0FBbUJMLFlBQW5CLEVBQWlDO0FBQzlDTSxJQUFBQSxRQUFRLEVBQUU7QUFEb0MsR0FBakMsQ0FBakI7O0FBR0EsU0FBT0gsUUFBUSxDQUFDUCxPQUFELENBQWY7QUFDSDs7QUFFTSxNQUFNVyxnQkFBTixDQUF1QjtBQUkxQkMsRUFBQUEsV0FBVyxDQUFDQyxHQUFELEVBQVdDLE9BQVgsRUFBZ0M7QUFBQTs7QUFBQTs7QUFDdkMsU0FBS0QsR0FBTCxHQUFXQSxHQUFYO0FBQ0EsU0FBS0MsT0FBTCxHQUFlQSxPQUFmO0FBQ0g7O0FBRURDLEVBQUFBLEtBQUssR0FBRztBQUNKLFVBQU1DLEdBQUcsR0FBR3ZCLE9BQU8sRUFBbkI7QUFDQXVCLElBQUFBLEdBQUcsQ0FBQ0MsR0FBSixDQUFReEIsT0FBTyxDQUFDeUIsSUFBUixFQUFSO0FBQ0FGLElBQUFBLEdBQUcsQ0FBQ0MsR0FBSixDQUFRdEIsSUFBSSxFQUFaO0FBQ0FxQixJQUFBQSxHQUFHLENBQUNHLEdBQUosQ0FBUSxHQUFSLEVBQWEsS0FBS0MsSUFBTCxDQUFVQyxJQUFWLENBQWUsSUFBZixDQUFiO0FBQ0FMLElBQUFBLEdBQUcsQ0FBQ00sTUFBSixDQUFXO0FBQUVDLE1BQUFBLElBQUksRUFBRSxLQUFLVCxPQUFMLENBQWFTO0FBQXJCLEtBQVgsRUFBd0MsTUFBTTtBQUMxQyxZQUFNQyxHQUFHLEdBQUksb0JBQW1CLEtBQUtWLE9BQUwsQ0FBYVMsSUFBSyxFQUFsRDtBQUNBRSxNQUFBQSxPQUFPLENBQUNDLEtBQVIsQ0FBZSxrQ0FBaUNGLEdBQUksRUFBcEQ7QUFDSCxLQUhEO0FBSUg7O0FBRUQsUUFBTUosSUFBTixDQUFXTyxHQUFYLEVBQXFCQyxHQUFyQixFQUErQjtBQUMzQixRQUFJO0FBQ0EsWUFBTUEsR0FBRyxDQUFDQyxJQUFKLENBQVMvQixhQUFhLENBQUMsTUFBRCxFQUFTLEtBQUtlLEdBQWQsQ0FBdEIsQ0FBTjtBQUNBZSxNQUFBQSxHQUFHLENBQUNFLEdBQUo7QUFDSCxLQUhELENBR0UsT0FBT0MsS0FBUCxFQUFjO0FBQ1pOLE1BQUFBLE9BQU8sQ0FBQ08sR0FBUixDQUFZLDhCQUFaLEVBQTRDRCxLQUE1QztBQUNBLFlBQU1ILEdBQUcsQ0FBQ1YsSUFBSixDQUFTO0FBQ1hlLFFBQUFBLE9BQU8sRUFBRSxLQURFO0FBRVhDLFFBQUFBLEVBQUUsRUFBRSxDQUZPO0FBR1hILFFBQUFBLEtBQUssRUFBRTtBQUNISSxVQUFBQSxJQUFJLEVBQUVDLE1BQU0sQ0FBQ0MsUUFBUCxDQUFnQk4sS0FBSyxJQUFJQSxLQUFLLENBQUNJLElBQS9CLEtBQXdDLENBRDNDO0FBRUhHLFVBQUFBLE9BQU8sRUFBRVAsS0FBSyxDQUFDTyxPQUFOLElBQWlCUCxLQUFLLENBQUNRLFFBQU4sRUFGdkI7QUFHSEMsVUFBQUEsSUFBSSxFQUFFVDtBQUhIO0FBSEksT0FBVCxDQUFOO0FBU0g7QUFDSjs7QUFwQ3lCOzs7O0FBdUN2QixlQUFlVSxHQUFmLENBQW1CNUIsR0FBbkIsRUFBNkJDLE9BQTdCLEVBQWtEO0FBQ3JELFFBQU00QixNQUFNLEdBQUcsSUFBSS9CLGdCQUFKLENBQXFCRSxHQUFyQixFQUEwQkMsT0FBMUIsQ0FBZjtBQUNBNEIsRUFBQUEsTUFBTSxDQUFDM0IsS0FBUDtBQUNBLFNBQU8sdUJBQVA7QUFDSCIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgMjAxOC0yMDIwIFRPTiBERVYgU09MVVRJT05TIExURC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgU09GVFdBUkUgRVZBTFVBVElPTiBMaWNlbnNlICh0aGUgXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2VcbiAqIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZVxuICogTGljZW5zZSBhdDogaHR0cHM6Ly93d3cudG9uLmRldi9saWNlbnNlc1xuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgVE9OIERFViBzb2Z0d2FyZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLy8gQGZsb3dcblxuaW1wb3J0IHR5cGUgeyBXZWJPcHRpb25zIH0gZnJvbSBcIi4uL2NsaS9vcHRpb25zXCI7XG5pbXBvcnQgeyBEZXYgfSBmcm9tIFwiLi4vZGV2XCI7XG5pbXBvcnQgeyBpbnB1dExpbmUgfSBmcm9tIFwiLi4vdXRpbHMvdXRpbHNcIjtcblxuY29uc3QgZXhwcmVzcyA9IHJlcXVpcmUoJ2V4cHJlc3MnKTtcbmNvbnN0IGNvcnMgPSByZXF1aXJlKCdjb3JzJyk7XG5pbXBvcnQgSGFuZGxlYmFycyBmcm9tICdoYW5kbGViYXJzJztcblxuY29uc3QgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcbmNvbnN0IGZzID0gcmVxdWlyZSgnZnMnKTtcblxuZnVuY3Rpb24gYXBwbHlUZW1wbGF0ZShuYW1lOiBzdHJpbmcsIGNvbnRleHQ6IGFueSk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgdGVtcGxhdGVQYXRoID0gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4uJywgJy4uJywgJ3NyYycsICdzZXJ2ZXInLCAndGVtcGxhdGVzJywgYCR7bmFtZX0uaGJzYCk7XG4gICAgY29uc3QgdGVtcGxhdGVUZXh0ID0gZnMucmVhZEZpbGVTeW5jKHRlbXBsYXRlUGF0aCwgeyBlbmNvZGluZzogJ3V0ZjgnIH0pO1xuICAgIGNvbnN0IHRlbXBsYXRlID0gSGFuZGxlYmFycy5jb21waWxlKHRlbXBsYXRlVGV4dCwge1xuICAgICAgICBub0VzY2FwZTogdHJ1ZSxcbiAgICB9KTtcbiAgICByZXR1cm4gdGVtcGxhdGUoY29udGV4dCk7XG59XG5cbmV4cG9ydCBjbGFzcyBUT05EZXZXZWJDb25zb2xlIHtcbiAgICBkZXY6IERldjtcbiAgICBvcHRpb25zOiBXZWJPcHRpb25zO1xuXG4gICAgY29uc3RydWN0b3IoZGV2OiBEZXYsIG9wdGlvbnM6IFdlYk9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5kZXYgPSBkZXY7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuXG4gICAgc3RhcnQoKSB7XG4gICAgICAgIGNvbnN0IGFwcCA9IGV4cHJlc3MoKTtcbiAgICAgICAgYXBwLnVzZShleHByZXNzLmpzb24oKSk7XG4gICAgICAgIGFwcC51c2UoY29ycygpKTtcbiAgICAgICAgYXBwLmdldCgnLycsIHRoaXMubWFpbi5iaW5kKHRoaXMpKTtcbiAgICAgICAgYXBwLmxpc3Rlbih7IHBvcnQ6IHRoaXMub3B0aW9ucy5wb3J0IH0sICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHVyaSA9IGBodHRwOi8vbG9jYWxob3N0OiR7dGhpcy5vcHRpb25zLnBvcnR9YDtcbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoYFRPTiBEZXYgV2ViIENvbnNvbGUgc3RhcnRlZCBvbiAke3VyaX1gKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYXN5bmMgbWFpbihyZXE6IGFueSwgcmVzOiBhbnkpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IHJlcy5zZW5kKGFwcGx5VGVtcGxhdGUoJ21haW4nLCB0aGlzLmRldikpO1xuICAgICAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ1tXZWIgQ29uc29sZV0gcmVxdWVzdCBmYWlsZWQnLCBlcnJvcik7XG4gICAgICAgICAgICBhd2FpdCByZXMuanNvbih7XG4gICAgICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICAgICAgaWQ6IDEsXG4gICAgICAgICAgICAgICAgZXJyb3I6IHtcbiAgICAgICAgICAgICAgICAgICAgY29kZTogTnVtYmVyLnBhcnNlSW50KGVycm9yICYmIGVycm9yLmNvZGUpIHx8IDEsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UgfHwgZXJyb3IudG9TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogZXJyb3JcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdlYihkZXY6IERldiwgb3B0aW9uczogV2ViT3B0aW9ucykge1xuICAgIGNvbnN0IHNlcnZlciA9IG5ldyBUT05EZXZXZWJDb25zb2xlKGRldiwgb3B0aW9ucyk7XG4gICAgc2VydmVyLnN0YXJ0KCk7XG4gICAgcmV0dXJuIGlucHV0TGluZSgpO1xufVxuIl19 -------------------------------------------------------------------------------- /dist/compilers/job.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.CompilersJob = void 0; 7 | 8 | var _dev = require("../dev"); 9 | 10 | var _utils = require("../utils/utils"); 11 | 12 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } 13 | 14 | const os = require('os'); 15 | 16 | class CompilersJob { 17 | constructor(dev, container, srcPath, dstPath) { 18 | _defineProperty(this, "dev", void 0); 19 | 20 | _defineProperty(this, "container", void 0); 21 | 22 | _defineProperty(this, "hostPath", void 0); 23 | 24 | _defineProperty(this, "guestPath", void 0); 25 | 26 | this.dev = dev; 27 | this.container = container; 28 | this.hostPath = srcPath; 29 | this.guestPath = dstPath; 30 | } 31 | 32 | static async create(dev, path) { 33 | const hostPath = (0, _utils.bindPathJoinTo)(path); 34 | const { 35 | container, 36 | guestPath 37 | } = await dev.getCompilersMountedTo(hostPath()); 38 | return new CompilersJob(dev, container, hostPath, guestPath); 39 | } 40 | 41 | async run(...args) { 42 | const container = this.container; 43 | 44 | if (os.platform() === 'win32') { 45 | return (0, _utils.run)('docker', 'exec', container.id, ...args); 46 | } 47 | 48 | return new Promise((resolve, reject) => { 49 | container.exec({ 50 | Cmd: args, 51 | Tty: true, 52 | AttachStdin: true, 53 | AttachStdout: true, 54 | AttachStderr: true 55 | }, (err, exec) => { 56 | if (err) { 57 | reject(err); 58 | return; 59 | } 60 | 61 | exec.start((err, stream) => { 62 | if (err) { 63 | reject(err); 64 | return; 65 | } 66 | 67 | container.modem.demuxStream(stream, process.stdout, process.stderr); 68 | 69 | const checkForResult = () => { 70 | exec.inspect((err, data) => { 71 | if (err) { 72 | reject(err); 73 | return; 74 | } 75 | 76 | if (data.Running) { 77 | setTimeout(checkForResult, 10); 78 | } else { 79 | resolve(data); 80 | } 81 | }); 82 | }; 83 | 84 | checkForResult(); 85 | }); 86 | }); 87 | }); 88 | } 89 | 90 | } 91 | 92 | exports.CompilersJob = CompilersJob; 93 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21waWxlcnMvam9iLmpzIl0sIm5hbWVzIjpbIm9zIiwicmVxdWlyZSIsIkNvbXBpbGVyc0pvYiIsImNvbnN0cnVjdG9yIiwiZGV2IiwiY29udGFpbmVyIiwic3JjUGF0aCIsImRzdFBhdGgiLCJob3N0UGF0aCIsImd1ZXN0UGF0aCIsImNyZWF0ZSIsInBhdGgiLCJnZXRDb21waWxlcnNNb3VudGVkVG8iLCJydW4iLCJhcmdzIiwicGxhdGZvcm0iLCJpZCIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiZXhlYyIsIkNtZCIsIlR0eSIsIkF0dGFjaFN0ZGluIiwiQXR0YWNoU3Rkb3V0IiwiQXR0YWNoU3RkZXJyIiwiZXJyIiwic3RhcnQiLCJzdHJlYW0iLCJtb2RlbSIsImRlbXV4U3RyZWFtIiwicHJvY2VzcyIsInN0ZG91dCIsInN0ZGVyciIsImNoZWNrRm9yUmVzdWx0IiwiaW5zcGVjdCIsImRhdGEiLCJSdW5uaW5nIiwic2V0VGltZW91dCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQWlCQTs7QUFHQTs7OztBQUNBLE1BQU1BLEVBQUUsR0FBR0MsT0FBTyxDQUFDLElBQUQsQ0FBbEI7O0FBRUEsTUFBTUMsWUFBTixDQUFtQjtBQU1mQyxFQUFBQSxXQUFXLENBQ1BDLEdBRE8sRUFFUEMsU0FGTyxFQUdQQyxPQUhPLEVBSVBDLE9BSk8sRUFLVDtBQUFBOztBQUFBOztBQUFBOztBQUFBOztBQUNFLFNBQUtILEdBQUwsR0FBV0EsR0FBWDtBQUNBLFNBQUtDLFNBQUwsR0FBaUJBLFNBQWpCO0FBQ0EsU0FBS0csUUFBTCxHQUFnQkYsT0FBaEI7QUFDQSxTQUFLRyxTQUFMLEdBQWlCRixPQUFqQjtBQUNIOztBQUVELGVBQWFHLE1BQWIsQ0FBb0JOLEdBQXBCLEVBQThCTyxJQUE5QixFQUE0QztBQUN4QyxVQUFNSCxRQUFRLEdBQUcsMkJBQWVHLElBQWYsQ0FBakI7QUFDQSxVQUFNO0FBQUNOLE1BQUFBLFNBQUQ7QUFBWUksTUFBQUE7QUFBWixRQUF5QixNQUFNTCxHQUFHLENBQUNRLHFCQUFKLENBQTBCSixRQUFRLEVBQWxDLENBQXJDO0FBQ0EsV0FBTyxJQUFJTixZQUFKLENBQWlCRSxHQUFqQixFQUFzQkMsU0FBdEIsRUFBaUNHLFFBQWpDLEVBQTJDQyxTQUEzQyxDQUFQO0FBQ0g7O0FBRUQsUUFBTUksR0FBTixDQUFVLEdBQUdDLElBQWIsRUFBNkI7QUFDekIsVUFBTVQsU0FBUyxHQUFHLEtBQUtBLFNBQXZCOztBQUNBLFFBQUlMLEVBQUUsQ0FBQ2UsUUFBSCxPQUFrQixPQUF0QixFQUErQjtBQUMzQixhQUFPLGdCQUFJLFFBQUosRUFBYyxNQUFkLEVBQXNCVixTQUFTLENBQUNXLEVBQWhDLEVBQW9DLEdBQUdGLElBQXZDLENBQVA7QUFDSDs7QUFDRCxXQUFPLElBQUlHLE9BQUosQ0FBWSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsS0FBcUI7QUFDcENkLE1BQUFBLFNBQVMsQ0FBQ2UsSUFBVixDQUFlO0FBQ1hDLFFBQUFBLEdBQUcsRUFBRVAsSUFETTtBQUVYUSxRQUFBQSxHQUFHLEVBQUUsSUFGTTtBQUdYQyxRQUFBQSxXQUFXLEVBQUUsSUFIRjtBQUlYQyxRQUFBQSxZQUFZLEVBQUUsSUFKSDtBQUtYQyxRQUFBQSxZQUFZLEVBQUU7QUFMSCxPQUFmLEVBTUcsQ0FBQ0MsR0FBRCxFQUFNTixJQUFOLEtBQWU7QUFDZCxZQUFJTSxHQUFKLEVBQVM7QUFDTFAsVUFBQUEsTUFBTSxDQUFDTyxHQUFELENBQU47QUFDQTtBQUNIOztBQUNETixRQUFBQSxJQUFJLENBQUNPLEtBQUwsQ0FBVyxDQUFDRCxHQUFELEVBQU1FLE1BQU4sS0FBaUI7QUFDeEIsY0FBSUYsR0FBSixFQUFTO0FBQ0xQLFlBQUFBLE1BQU0sQ0FBQ08sR0FBRCxDQUFOO0FBQ0E7QUFDSDs7QUFFRHJCLFVBQUFBLFNBQVMsQ0FBQ3dCLEtBQVYsQ0FBZ0JDLFdBQWhCLENBQTRCRixNQUE1QixFQUFvQ0csT0FBTyxDQUFDQyxNQUE1QyxFQUFvREQsT0FBTyxDQUFDRSxNQUE1RDs7QUFFQSxnQkFBTUMsY0FBYyxHQUFHLE1BQU07QUFDekJkLFlBQUFBLElBQUksQ0FBQ2UsT0FBTCxDQUFhLENBQUNULEdBQUQsRUFBTVUsSUFBTixLQUFlO0FBQ3hCLGtCQUFJVixHQUFKLEVBQVM7QUFDTFAsZ0JBQUFBLE1BQU0sQ0FBQ08sR0FBRCxDQUFOO0FBQ0E7QUFDSDs7QUFDRCxrQkFBSVUsSUFBSSxDQUFDQyxPQUFULEVBQWtCO0FBQ2RDLGdCQUFBQSxVQUFVLENBQUNKLGNBQUQsRUFBaUIsRUFBakIsQ0FBVjtBQUNILGVBRkQsTUFFTztBQUNIaEIsZ0JBQUFBLE9BQU8sQ0FBQ2tCLElBQUQsQ0FBUDtBQUNIO0FBQ0osYUFWRDtBQVdILFdBWkQ7O0FBYUFGLFVBQUFBLGNBQWM7QUFDakIsU0F0QkQ7QUF1QkgsT0FsQ0Q7QUFtQ0gsS0FwQ00sQ0FBUDtBQXFDSDs7QUFsRWMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IDIwMTgtMjAyMCBUT04gREVWIFNPTFVUSU9OUyBMVEQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIFNPRlRXQVJFIEVWQUxVQVRJT04gTGljZW5zZSAodGhlIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlXG4gKiB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGVcbiAqIExpY2Vuc2UgYXQ6IGh0dHBzOi8vd3d3LnRvbi5kZXYvbGljZW5zZXNcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIFRPTiBERVYgc29mdHdhcmUgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbi8vIEBmbG93XG5cbmltcG9ydCB7IERldiB9IGZyb20gXCIuLi9kZXZcIjtcbmltcG9ydCB0eXBlIHsgRG9ja2VyQ29udGFpbmVyIH0gZnJvbSBcIi4uL3V0aWxzL2RvY2tlclwiO1xuaW1wb3J0IHR5cGUgeyBQYXRoSm9pbiB9IGZyb20gXCIuLi91dGlscy91dGlsc1wiO1xuaW1wb3J0IHsgYmluZFBhdGhKb2luVG8sIHJ1biB9IGZyb20gXCIuLi91dGlscy91dGlsc1wiO1xuY29uc3Qgb3MgPSByZXF1aXJlKCdvcycpO1xuXG5jbGFzcyBDb21waWxlcnNKb2Ige1xuICAgIGRldjogRGV2O1xuICAgIGNvbnRhaW5lcjogRG9ja2VyQ29udGFpbmVyO1xuICAgIGhvc3RQYXRoOiBQYXRoSm9pbjtcbiAgICBndWVzdFBhdGg6IFBhdGhKb2luO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIGRldjogRGV2LFxuICAgICAgICBjb250YWluZXI6IERvY2tlckNvbnRhaW5lcixcbiAgICAgICAgc3JjUGF0aDogUGF0aEpvaW4sXG4gICAgICAgIGRzdFBhdGg6IFBhdGhKb2luLFxuICAgICkge1xuICAgICAgICB0aGlzLmRldiA9IGRldjtcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSBjb250YWluZXI7XG4gICAgICAgIHRoaXMuaG9zdFBhdGggPSBzcmNQYXRoO1xuICAgICAgICB0aGlzLmd1ZXN0UGF0aCA9IGRzdFBhdGg7XG4gICAgfVxuXG4gICAgc3RhdGljIGFzeW5jIGNyZWF0ZShkZXY6IERldiwgcGF0aDogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IGhvc3RQYXRoID0gYmluZFBhdGhKb2luVG8ocGF0aCk7XG4gICAgICAgIGNvbnN0IHtjb250YWluZXIsIGd1ZXN0UGF0aH0gPSBhd2FpdCBkZXYuZ2V0Q29tcGlsZXJzTW91bnRlZFRvKGhvc3RQYXRoKCkpO1xuICAgICAgICByZXR1cm4gbmV3IENvbXBpbGVyc0pvYihkZXYsIGNvbnRhaW5lciwgaG9zdFBhdGgsIGd1ZXN0UGF0aCk7XG4gICAgfVxuXG4gICAgYXN5bmMgcnVuKC4uLmFyZ3M6IHN0cmluZ1tdKSB7XG4gICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuY29udGFpbmVyO1xuICAgICAgICBpZiAob3MucGxhdGZvcm0oKSA9PT0gJ3dpbjMyJykge1xuICAgICAgICAgICAgcmV0dXJuIHJ1bignZG9ja2VyJywgJ2V4ZWMnLCBjb250YWluZXIuaWQsIC4uLmFyZ3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb250YWluZXIuZXhlYyh7XG4gICAgICAgICAgICAgICAgQ21kOiBhcmdzLFxuICAgICAgICAgICAgICAgIFR0eTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBBdHRhY2hTdGRpbjogdHJ1ZSxcbiAgICAgICAgICAgICAgICBBdHRhY2hTdGRvdXQ6IHRydWUsXG4gICAgICAgICAgICAgICAgQXR0YWNoU3RkZXJyOiB0cnVlLFxuICAgICAgICAgICAgfSwgKGVyciwgZXhlYykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZXhlYy5zdGFydCgoZXJyLCBzdHJlYW0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb250YWluZXIubW9kZW0uZGVtdXhTdHJlYW0oc3RyZWFtLCBwcm9jZXNzLnN0ZG91dCwgcHJvY2Vzcy5zdGRlcnIpO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoZWNrRm9yUmVzdWx0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXhlYy5pbnNwZWN0KChlcnIsIGRhdGEpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhLlJ1bm5pbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChjaGVja0ZvclJlc3VsdCwgMTApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIGNoZWNrRm9yUmVzdWx0KCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG59XG5cbmV4cG9ydCB7XG4gICAgQ29tcGlsZXJzSm9iXG59XG4iXX0= -------------------------------------------------------------------------------- /dist/networks/networks.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.Network = void 0; 7 | 8 | var _docker = require("../utils/docker"); 9 | 10 | var _utils = require("../utils/utils"); 11 | 12 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } 13 | 14 | class Network { 15 | constructor(config) { 16 | _defineProperty(this, "name", void 0); 17 | 18 | _defineProperty(this, "version", void 0); 19 | 20 | _defineProperty(this, "hostPort", void 0); 21 | 22 | _defineProperty(this, "arangoHostPort", void 0); 23 | 24 | _defineProperty(this, "requiredImage", void 0); 25 | 26 | _defineProperty(this, "containerName", void 0); 27 | 28 | this.setConfig(config); 29 | } 30 | 31 | setConfig(config) { 32 | this.name = config.name; 33 | this.version = config.version; 34 | this.hostPort = config.hostPort || ''; 35 | this.arangoHostPort = config.arangoHostPort || ''; 36 | this.requiredImage = `${Network.imagePrefix}:${config.version}`; 37 | const suffix = config.name !== Network.defaultName ? `-${config.name}` : ''; 38 | this.containerName = `${Network.containerPrefix}-${_utils.userIdentifier}${suffix}`; 39 | } 40 | 41 | getConfig() { 42 | return { 43 | name: this.name, 44 | version: this.version, 45 | hostPort: this.hostPort, 46 | arangoHostPort: this.arangoHostPort 47 | }; 48 | } 49 | 50 | async createContainer(docker) { 51 | const ports = { 52 | '80/tcp': [{ 53 | HostIp: '', 54 | HostPort: `${this.hostPort}` 55 | }] 56 | }; 57 | 58 | if (this.arangoHostPort !== '') { 59 | ports['8529/tcp'] = [{ 60 | HostIp: '', 61 | HostPort: this.arangoHostPort 62 | }]; 63 | } 64 | 65 | return docker.client.createContainer({ 66 | name: this.containerName, 67 | interactive: true, 68 | Image: this.requiredImage, 69 | Env: ['USER_AGREEMENT=yes'], 70 | HostConfig: { 71 | PortBindings: ports 72 | } 73 | }); 74 | } 75 | 76 | } 77 | 78 | exports.Network = Network; 79 | 80 | _defineProperty(Network, "imagePrefix", 'tonlabs/local-node'); 81 | 82 | _defineProperty(Network, "containerPrefix", 'tonlabs-local-node'); 83 | 84 | _defineProperty(Network, "defaultName", 'default'); 85 | 86 | _defineProperty(Network, "defaultConfig", Object.freeze({ 87 | name: 'default', 88 | version: 'latest', 89 | hostPort: '80', 90 | arangoHostPort: '' 91 | })); 92 | 93 | _defineProperty(Network, "defaultArangoPort", '8529'); 94 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9uZXR3b3Jrcy9uZXR3b3Jrcy5qcyJdLCJuYW1lcyI6WyJOZXR3b3JrIiwiY29uc3RydWN0b3IiLCJjb25maWciLCJzZXRDb25maWciLCJuYW1lIiwidmVyc2lvbiIsImhvc3RQb3J0IiwiYXJhbmdvSG9zdFBvcnQiLCJyZXF1aXJlZEltYWdlIiwiaW1hZ2VQcmVmaXgiLCJzdWZmaXgiLCJkZWZhdWx0TmFtZSIsImNvbnRhaW5lck5hbWUiLCJjb250YWluZXJQcmVmaXgiLCJ1c2VySWRlbnRpZmllciIsImdldENvbmZpZyIsImNyZWF0ZUNvbnRhaW5lciIsImRvY2tlciIsInBvcnRzIiwiSG9zdElwIiwiSG9zdFBvcnQiLCJjbGllbnQiLCJpbnRlcmFjdGl2ZSIsIkltYWdlIiwiRW52IiwiSG9zdENvbmZpZyIsIlBvcnRCaW5kaW5ncyIsIk9iamVjdCIsImZyZWV6ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQWtCQTs7QUFDQTs7OztBQVNBLE1BQU1BLE9BQU4sQ0FBc0M7QUFtQmxDQyxFQUFBQSxXQUFXLENBQUNDLE1BQUQsRUFBd0I7QUFBQTs7QUFBQTs7QUFBQTs7QUFBQTs7QUFBQTs7QUFBQTs7QUFDL0IsU0FBS0MsU0FBTCxDQUFlRCxNQUFmO0FBQ0g7O0FBRURDLEVBQUFBLFNBQVMsQ0FBQ0QsTUFBRCxFQUF3QjtBQUM3QixTQUFLRSxJQUFMLEdBQVlGLE1BQU0sQ0FBQ0UsSUFBbkI7QUFDQSxTQUFLQyxPQUFMLEdBQWVILE1BQU0sQ0FBQ0csT0FBdEI7QUFDQSxTQUFLQyxRQUFMLEdBQWdCSixNQUFNLENBQUNJLFFBQVAsSUFBbUIsRUFBbkM7QUFDQSxTQUFLQyxjQUFMLEdBQXNCTCxNQUFNLENBQUNLLGNBQVAsSUFBeUIsRUFBL0M7QUFDQSxTQUFLQyxhQUFMLEdBQXNCLEdBQUVSLE9BQU8sQ0FBQ1MsV0FBWSxJQUFHUCxNQUFNLENBQUNHLE9BQVEsRUFBOUQ7QUFDQSxVQUFNSyxNQUFNLEdBQUdSLE1BQU0sQ0FBQ0UsSUFBUCxLQUFnQkosT0FBTyxDQUFDVyxXQUF4QixHQUF1QyxJQUFHVCxNQUFNLENBQUNFLElBQUssRUFBdEQsR0FBMEQsRUFBekU7QUFDQSxTQUFLUSxhQUFMLEdBQXNCLEdBQUVaLE9BQU8sQ0FBQ2EsZUFBZ0IsSUFBR0MscUJBQWUsR0FBRUosTUFBTyxFQUEzRTtBQUNIOztBQUVESyxFQUFBQSxTQUFTLEdBQWtCO0FBQ3ZCLFdBQU87QUFDSFgsTUFBQUEsSUFBSSxFQUFFLEtBQUtBLElBRFI7QUFFSEMsTUFBQUEsT0FBTyxFQUFFLEtBQUtBLE9BRlg7QUFHSEMsTUFBQUEsUUFBUSxFQUFFLEtBQUtBLFFBSFo7QUFJSEMsTUFBQUEsY0FBYyxFQUFFLEtBQUtBO0FBSmxCLEtBQVA7QUFNSDs7QUFFRCxRQUFNUyxlQUFOLENBQXNCQyxNQUF0QixFQUFtRTtBQUMvRCxVQUFNQyxLQUFvQixHQUFHO0FBQ3pCLGdCQUFVLENBQ047QUFDSUMsUUFBQUEsTUFBTSxFQUFFLEVBRFo7QUFFSUMsUUFBQUEsUUFBUSxFQUFHLEdBQUUsS0FBS2QsUUFBUztBQUYvQixPQURNO0FBRGUsS0FBN0I7O0FBUUEsUUFBSSxLQUFLQyxjQUFMLEtBQXdCLEVBQTVCLEVBQWdDO0FBQzVCVyxNQUFBQSxLQUFLLENBQUMsVUFBRCxDQUFMLEdBQW9CLENBQ2hCO0FBQ0lDLFFBQUFBLE1BQU0sRUFBRSxFQURaO0FBRUlDLFFBQUFBLFFBQVEsRUFBRSxLQUFLYjtBQUZuQixPQURnQixDQUFwQjtBQU1IOztBQUNELFdBQU9VLE1BQU0sQ0FBQ0ksTUFBUCxDQUFjTCxlQUFkLENBQThCO0FBQ2pDWixNQUFBQSxJQUFJLEVBQUUsS0FBS1EsYUFEc0I7QUFFakNVLE1BQUFBLFdBQVcsRUFBRSxJQUZvQjtBQUdqQ0MsTUFBQUEsS0FBSyxFQUFFLEtBQUtmLGFBSHFCO0FBSWpDZ0IsTUFBQUEsR0FBRyxFQUFFLENBQUMsb0JBQUQsQ0FKNEI7QUFLakNDLE1BQUFBLFVBQVUsRUFBRTtBQUNSQyxRQUFBQSxZQUFZLEVBQUVSO0FBRE47QUFMcUIsS0FBOUIsQ0FBUDtBQVNIOztBQXBFaUM7Ozs7Z0JBQWhDbEIsTyxpQkFDbUIsb0I7O2dCQURuQkEsTyxxQkFFdUIsb0I7O2dCQUZ2QkEsTyxpQkFHbUIsUzs7Z0JBSG5CQSxPLG1CQUlvQzJCLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjO0FBQ2hEeEIsRUFBQUEsSUFBSSxFQUFFLFNBRDBDO0FBRWhEQyxFQUFBQSxPQUFPLEVBQUUsUUFGdUM7QUFHaERDLEVBQUFBLFFBQVEsRUFBRSxJQUhzQztBQUloREMsRUFBQUEsY0FBYyxFQUFFO0FBSmdDLENBQWQsQzs7Z0JBSnBDUCxPLHVCQVV5QixNIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAyMDE4LTIwMjAgVE9OIERFViBTT0xVVElPTlMgTFRELlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBTT0ZUV0FSRSBFVkFMVUFUSU9OIExpY2Vuc2UgKHRoZSBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZVxuICogdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlXG4gKiBMaWNlbnNlIGF0OiBodHRwczovL3d3dy50b24uZGV2L2xpY2Vuc2VzXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBUT04gREVWIHNvZnR3YXJlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vLyBAZmxvd1xuXG5pbXBvcnQgdHlwZSB7IENvbnRhaW5lckRlZiwgRG9ja2VyQ29udGFpbmVyLCBEUG9ydEJpbmRpbmdzIH0gZnJvbSBcIi4uL3V0aWxzL2RvY2tlclwiO1xuaW1wb3J0IHsgRGV2RG9ja2VyIH0gZnJvbSBcIi4uL3V0aWxzL2RvY2tlclwiO1xuaW1wb3J0IHsgdXNlcklkZW50aWZpZXIgfSBmcm9tIFwiLi4vdXRpbHMvdXRpbHNcIjtcblxuZXhwb3J0IHR5cGUgTmV0d29ya0NvbmZpZyA9IHtcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgdmVyc2lvbjogc3RyaW5nLFxuICAgIGhvc3RQb3J0OiBzdHJpbmcsXG4gICAgYXJhbmdvSG9zdFBvcnQ6IHN0cmluZyxcbn07XG5cbmNsYXNzIE5ldHdvcmsgaW1wbGVtZW50cyBDb250YWluZXJEZWYge1xuICAgIHN0YXRpYyBpbWFnZVByZWZpeCA9ICd0b25sYWJzL2xvY2FsLW5vZGUnO1xuICAgIHN0YXRpYyBjb250YWluZXJQcmVmaXggPSAndG9ubGFicy1sb2NhbC1ub2RlJztcbiAgICBzdGF0aWMgZGVmYXVsdE5hbWUgPSAnZGVmYXVsdCc7XG4gICAgc3RhdGljIGRlZmF1bHRDb25maWc6IE5ldHdvcmtDb25maWcgPSBPYmplY3QuZnJlZXplKHtcbiAgICAgICAgbmFtZTogJ2RlZmF1bHQnLFxuICAgICAgICB2ZXJzaW9uOiAnbGF0ZXN0JyxcbiAgICAgICAgaG9zdFBvcnQ6ICc4MCcsXG4gICAgICAgIGFyYW5nb0hvc3RQb3J0OiAnJyxcbiAgICB9KTtcbiAgICBzdGF0aWMgZGVmYXVsdEFyYW5nb1BvcnQgPSAnODUyOSc7XG5cbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgdmVyc2lvbjogc3RyaW5nO1xuICAgIGhvc3RQb3J0OiBzdHJpbmc7XG4gICAgYXJhbmdvSG9zdFBvcnQ6IHN0cmluZztcbiAgICByZXF1aXJlZEltYWdlOiBzdHJpbmc7XG4gICAgY29udGFpbmVyTmFtZTogc3RyaW5nO1xuXG4gICAgY29uc3RydWN0b3IoY29uZmlnOiBOZXR3b3JrQ29uZmlnKSB7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKGNvbmZpZyk7XG4gICAgfVxuXG4gICAgc2V0Q29uZmlnKGNvbmZpZzogTmV0d29ya0NvbmZpZykge1xuICAgICAgICB0aGlzLm5hbWUgPSBjb25maWcubmFtZTtcbiAgICAgICAgdGhpcy52ZXJzaW9uID0gY29uZmlnLnZlcnNpb247XG4gICAgICAgIHRoaXMuaG9zdFBvcnQgPSBjb25maWcuaG9zdFBvcnQgfHwgJyc7XG4gICAgICAgIHRoaXMuYXJhbmdvSG9zdFBvcnQgPSBjb25maWcuYXJhbmdvSG9zdFBvcnQgfHwgJyc7XG4gICAgICAgIHRoaXMucmVxdWlyZWRJbWFnZSA9IGAke05ldHdvcmsuaW1hZ2VQcmVmaXh9OiR7Y29uZmlnLnZlcnNpb259YDtcbiAgICAgICAgY29uc3Qgc3VmZml4ID0gY29uZmlnLm5hbWUgIT09IE5ldHdvcmsuZGVmYXVsdE5hbWUgPyBgLSR7Y29uZmlnLm5hbWV9YCA6ICcnO1xuICAgICAgICB0aGlzLmNvbnRhaW5lck5hbWUgPSBgJHtOZXR3b3JrLmNvbnRhaW5lclByZWZpeH0tJHt1c2VySWRlbnRpZmllcn0ke3N1ZmZpeH1gO1xuICAgIH1cblxuICAgIGdldENvbmZpZygpOiBOZXR3b3JrQ29uZmlnIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgICAgIHZlcnNpb246IHRoaXMudmVyc2lvbixcbiAgICAgICAgICAgIGhvc3RQb3J0OiB0aGlzLmhvc3RQb3J0LFxuICAgICAgICAgICAgYXJhbmdvSG9zdFBvcnQ6IHRoaXMuYXJhbmdvSG9zdFBvcnRcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIGNyZWF0ZUNvbnRhaW5lcihkb2NrZXI6IERldkRvY2tlcik6IFByb21pc2U8RG9ja2VyQ29udGFpbmVyPiB7XG4gICAgICAgIGNvbnN0IHBvcnRzOiBEUG9ydEJpbmRpbmdzID0ge1xuICAgICAgICAgICAgJzgwL3RjcCc6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIEhvc3RJcDogJycsXG4gICAgICAgICAgICAgICAgICAgIEhvc3RQb3J0OiBgJHt0aGlzLmhvc3RQb3J0fWAsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgIH07XG4gICAgICAgIGlmICh0aGlzLmFyYW5nb0hvc3RQb3J0ICE9PSAnJykge1xuICAgICAgICAgICAgcG9ydHNbJzg1MjkvdGNwJ10gPSBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBIb3N0SXA6ICcnLFxuICAgICAgICAgICAgICAgICAgICBIb3N0UG9ydDogdGhpcy5hcmFuZ29Ib3N0UG9ydCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkb2NrZXIuY2xpZW50LmNyZWF0ZUNvbnRhaW5lcih7XG4gICAgICAgICAgICBuYW1lOiB0aGlzLmNvbnRhaW5lck5hbWUsXG4gICAgICAgICAgICBpbnRlcmFjdGl2ZTogdHJ1ZSxcbiAgICAgICAgICAgIEltYWdlOiB0aGlzLnJlcXVpcmVkSW1hZ2UsXG4gICAgICAgICAgICBFbnY6IFsnVVNFUl9BR1JFRU1FTlQ9eWVzJ10sXG4gICAgICAgICAgICBIb3N0Q29uZmlnOiB7XG4gICAgICAgICAgICAgICAgUG9ydEJpbmRpbmdzOiBwb3J0cyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuXG5leHBvcnQge1xuICAgIE5ldHdvcmtcbn1cbiJdfQ== -------------------------------------------------------------------------------- /dist/utils/texts.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.texts = void 0; 7 | const texts = { 8 | agreementConfirmation: ` 9 | This Agreement takes effect when you input a “YES” and press Enter 10 | or, if earlier, when you use any of the TON DEV Software: `, 11 | agreementRejected: '\n\nLicense terms were not accepted.\n', 12 | agreementAccepted: '\n\nLicense terms were accepted.\n', 13 | dockerVersionRequired: "Docker version required ^17", 14 | noTonDevImages: 'There are no TON Dev Images', 15 | noTonDevContainers: 'There are no TON Dev Containers', 16 | done: ' Done.', 17 | netsHeader: 'Local nets:', 18 | compilerHeader: 'Compilers:', 19 | availableVersions: 'Available versions:', 20 | 21 | containerDoesNotExists(name) { 22 | return `Container [${name}] does not exists. Creating...`; 23 | }, 24 | 25 | imageDoesNotExists(name) { 26 | return `Image [${name}] is missing. Pulling (please wait)...`; 27 | }, 28 | 29 | containerCanNotBeCreated(name) { 30 | return `Container [${name}] can not be created`; 31 | }, 32 | 33 | containerHaveBeenRemoved(id) { 34 | return `Container [${id} have been removed.`; 35 | }, 36 | 37 | imageHaveBeenRemoved(id) { 38 | return `Image [${id} have been removed.`; 39 | }, 40 | 41 | sourceFileNotFound(name) { 42 | return `Source file [${name}] not found.`; 43 | }, 44 | 45 | usageHeader(version) { 46 | return `TON Labs Dev Tools ${version}`; 47 | }, 48 | 49 | invalidOption(arg) { 50 | return `Invalid option: ${arg}`; 51 | }, 52 | 53 | usage: `usage: tondev command { argument ... } 54 | 55 | Options: 56 | -p, --port Set local port number for local net 57 | -n, --net Set local net name to which command applied, can be specified multiple times 58 | -i, --images Apply command only to docker images 59 | -c, --containers Apply command only to docker containers 60 | -js, --JavaScript Generate additional JavaScript code 61 | 62 | 63 | Commands: 64 | sol Build TON contract from solidity source code 65 | start Start local net (if net name does not specified the all nets will be started) 66 | stop Stop compilers and all nets 67 | info Show current status of compilers and nets 68 | setup Looking for a required prerequisites and setup required additional components 69 | clean Remove all TON Dev docker containers and images 70 | use Select version for compilers and nets 71 | 72 | Copyright 2018-2020 TON DEV SOLUTIONS LTD. 73 | Licensed under the SOFTWARE EVALUATION License (https://www.ton.dev/licenses) 74 | `, 75 | 76 | tonDevImages() { 77 | return `Images:`; 78 | }, 79 | 80 | tonDevContainers() { 81 | return `Containers:`; 82 | }, 83 | 84 | netHeader(name) { 85 | return `${name} network/blockchain:`; 86 | }, 87 | 88 | usedVersion(version) { 89 | return ` Used version: ${version}`; 90 | }, 91 | 92 | netHostPort(port) { 93 | return ` Bound to host port: ${port}`; 94 | }, 95 | 96 | netArangoHostPort(port) { 97 | return ` Arango DB is bound to host port: ${port}`; 98 | } 99 | 100 | }; 101 | exports.texts = texts; 102 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy90ZXh0cy5qcyJdLCJuYW1lcyI6WyJ0ZXh0cyIsImFncmVlbWVudENvbmZpcm1hdGlvbiIsImFncmVlbWVudFJlamVjdGVkIiwiYWdyZWVtZW50QWNjZXB0ZWQiLCJkb2NrZXJWZXJzaW9uUmVxdWlyZWQiLCJub1RvbkRldkltYWdlcyIsIm5vVG9uRGV2Q29udGFpbmVycyIsImRvbmUiLCJuZXRzSGVhZGVyIiwiY29tcGlsZXJIZWFkZXIiLCJhdmFpbGFibGVWZXJzaW9ucyIsImNvbnRhaW5lckRvZXNOb3RFeGlzdHMiLCJuYW1lIiwiaW1hZ2VEb2VzTm90RXhpc3RzIiwiY29udGFpbmVyQ2FuTm90QmVDcmVhdGVkIiwiY29udGFpbmVySGF2ZUJlZW5SZW1vdmVkIiwiaWQiLCJpbWFnZUhhdmVCZWVuUmVtb3ZlZCIsInNvdXJjZUZpbGVOb3RGb3VuZCIsInVzYWdlSGVhZGVyIiwidmVyc2lvbiIsImludmFsaWRPcHRpb24iLCJhcmciLCJ1c2FnZSIsInRvbkRldkltYWdlcyIsInRvbkRldkNvbnRhaW5lcnMiLCJuZXRIZWFkZXIiLCJ1c2VkVmVyc2lvbiIsIm5ldEhvc3RQb3J0IiwicG9ydCIsIm5ldEFyYW5nb0hvc3RQb3J0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxNQUFNQSxLQUFLLEdBQUc7QUFDVkMsRUFBQUEscUJBQXFCLEVBQUc7OzJEQURkO0FBSVZDLEVBQUFBLGlCQUFpQixFQUFFLHdDQUpUO0FBS1ZDLEVBQUFBLGlCQUFpQixFQUFFLG9DQUxUO0FBTVZDLEVBQUFBLHFCQUFxQixFQUFFLDZCQU5iO0FBT1ZDLEVBQUFBLGNBQWMsRUFBRSw2QkFQTjtBQVFWQyxFQUFBQSxrQkFBa0IsRUFBRSxpQ0FSVjtBQVNWQyxFQUFBQSxJQUFJLEVBQUUsUUFUSTtBQVVWQyxFQUFBQSxVQUFVLEVBQUUsYUFWRjtBQVdWQyxFQUFBQSxjQUFjLEVBQUUsWUFYTjtBQVlWQyxFQUFBQSxpQkFBaUIsRUFBRSxxQkFaVDs7QUFhVkMsRUFBQUEsc0JBQXNCLENBQUNDLElBQUQsRUFBTztBQUN6QixXQUFRLGNBQWFBLElBQUssZ0NBQTFCO0FBQ0gsR0FmUzs7QUFnQlZDLEVBQUFBLGtCQUFrQixDQUFDRCxJQUFELEVBQU87QUFDckIsV0FBUSxVQUFTQSxJQUFLLHdDQUF0QjtBQUNILEdBbEJTOztBQW1CVkUsRUFBQUEsd0JBQXdCLENBQUNGLElBQUQsRUFBTztBQUMzQixXQUFRLGNBQWFBLElBQUssc0JBQTFCO0FBQ0gsR0FyQlM7O0FBc0JWRyxFQUFBQSx3QkFBd0IsQ0FBQ0MsRUFBRCxFQUFLO0FBQ3pCLFdBQVEsY0FBYUEsRUFBRyxxQkFBeEI7QUFDSCxHQXhCUzs7QUF5QlZDLEVBQUFBLG9CQUFvQixDQUFDRCxFQUFELEVBQUs7QUFDckIsV0FBUSxVQUFTQSxFQUFHLHFCQUFwQjtBQUNILEdBM0JTOztBQTRCVkUsRUFBQUEsa0JBQWtCLENBQUNOLElBQUQsRUFBTztBQUNyQixXQUFRLGdCQUFlQSxJQUFLLGNBQTVCO0FBQ0gsR0E5QlM7O0FBK0JWTyxFQUFBQSxXQUFXLENBQUNDLE9BQUQsRUFBVTtBQUNqQixXQUFRLHNCQUFxQkEsT0FBUSxFQUFyQztBQUNILEdBakNTOztBQWtDVkMsRUFBQUEsYUFBYSxDQUFDQyxHQUFELEVBQU07QUFDZixXQUFRLG1CQUFrQkEsR0FBSSxFQUE5QjtBQUNILEdBcENTOztBQXFDVkMsRUFBQUEsS0FBSyxFQUFHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0FyQ0U7O0FBMkRWQyxFQUFBQSxZQUFZLEdBQUc7QUFDWCxXQUFRLFNBQVI7QUFDSCxHQTdEUzs7QUE4RFZDLEVBQUFBLGdCQUFnQixHQUFHO0FBQ2YsV0FBUSxhQUFSO0FBQ0gsR0FoRVM7O0FBaUVWQyxFQUFBQSxTQUFTLENBQUNkLElBQUQsRUFBTztBQUNaLFdBQVEsR0FBRUEsSUFBSyxzQkFBZjtBQUNILEdBbkVTOztBQW9FVmUsRUFBQUEsV0FBVyxDQUFDUCxPQUFELEVBQVU7QUFDakIsV0FBUSxtQkFBa0JBLE9BQVEsRUFBbEM7QUFDSCxHQXRFUzs7QUF1RVZRLEVBQUFBLFdBQVcsQ0FBQ0MsSUFBRCxFQUFPO0FBQ2QsV0FBUSx5QkFBd0JBLElBQUssRUFBckM7QUFDSCxHQXpFUzs7QUEwRVZDLEVBQUFBLGlCQUFpQixDQUFDRCxJQUFELEVBQU87QUFDcEIsV0FBUSxzQ0FBcUNBLElBQUssRUFBbEQ7QUFDSDs7QUE1RVMsQ0FBZCIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHRleHRzID0ge1xuICAgIGFncmVlbWVudENvbmZpcm1hdGlvbjogYFxuVGhpcyBBZ3JlZW1lbnQgdGFrZXMgZWZmZWN0IHdoZW4geW91IGlucHV0IGEg4oCcWUVT4oCdIGFuZCBwcmVzcyBFbnRlciBcbm9yLCBpZiBlYXJsaWVyLCB3aGVuIHlvdSB1c2UgYW55IG9mIHRoZSBUT04gREVWIFNvZnR3YXJlOiBgLFxuICAgIGFncmVlbWVudFJlamVjdGVkOiAnXFxuXFxuTGljZW5zZSB0ZXJtcyB3ZXJlIG5vdCBhY2NlcHRlZC5cXG4nLFxuICAgIGFncmVlbWVudEFjY2VwdGVkOiAnXFxuXFxuTGljZW5zZSB0ZXJtcyB3ZXJlIGFjY2VwdGVkLlxcbicsXG4gICAgZG9ja2VyVmVyc2lvblJlcXVpcmVkOiBcIkRvY2tlciB2ZXJzaW9uIHJlcXVpcmVkIF4xN1wiLFxuICAgIG5vVG9uRGV2SW1hZ2VzOiAnVGhlcmUgYXJlIG5vIFRPTiBEZXYgSW1hZ2VzJyxcbiAgICBub1RvbkRldkNvbnRhaW5lcnM6ICdUaGVyZSBhcmUgbm8gVE9OIERldiBDb250YWluZXJzJyxcbiAgICBkb25lOiAnIERvbmUuJyxcbiAgICBuZXRzSGVhZGVyOiAnTG9jYWwgbmV0czonLFxuICAgIGNvbXBpbGVySGVhZGVyOiAnQ29tcGlsZXJzOicsXG4gICAgYXZhaWxhYmxlVmVyc2lvbnM6ICdBdmFpbGFibGUgdmVyc2lvbnM6JyxcbiAgICBjb250YWluZXJEb2VzTm90RXhpc3RzKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGBDb250YWluZXIgWyR7bmFtZX1dIGRvZXMgbm90IGV4aXN0cy4gQ3JlYXRpbmcuLi5gO1xuICAgIH0sXG4gICAgaW1hZ2VEb2VzTm90RXhpc3RzKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGBJbWFnZSBbJHtuYW1lfV0gaXMgbWlzc2luZy4gUHVsbGluZyAocGxlYXNlIHdhaXQpLi4uYDtcbiAgICB9LFxuICAgIGNvbnRhaW5lckNhbk5vdEJlQ3JlYXRlZChuYW1lKSB7XG4gICAgICAgIHJldHVybiBgQ29udGFpbmVyIFske25hbWV9XSBjYW4gbm90IGJlIGNyZWF0ZWRgO1xuICAgIH0sXG4gICAgY29udGFpbmVySGF2ZUJlZW5SZW1vdmVkKGlkKSB7XG4gICAgICAgIHJldHVybiBgQ29udGFpbmVyIFske2lkfSBoYXZlIGJlZW4gcmVtb3ZlZC5gO1xuICAgIH0sXG4gICAgaW1hZ2VIYXZlQmVlblJlbW92ZWQoaWQpIHtcbiAgICAgICAgcmV0dXJuIGBJbWFnZSBbJHtpZH0gaGF2ZSBiZWVuIHJlbW92ZWQuYDtcbiAgICB9LFxuICAgIHNvdXJjZUZpbGVOb3RGb3VuZChuYW1lKSB7XG4gICAgICAgIHJldHVybiBgU291cmNlIGZpbGUgWyR7bmFtZX1dIG5vdCBmb3VuZC5gO1xuICAgIH0sXG4gICAgdXNhZ2VIZWFkZXIodmVyc2lvbikge1xuICAgICAgICByZXR1cm4gYFRPTiBMYWJzIERldiBUb29scyAke3ZlcnNpb259YDtcbiAgICB9LFxuICAgIGludmFsaWRPcHRpb24oYXJnKSB7XG4gICAgICAgIHJldHVybiBgSW52YWxpZCBvcHRpb246ICR7YXJnfWA7XG4gICAgfSxcbiAgICB1c2FnZTogYHVzYWdlOiB0b25kZXYgY29tbWFuZCB7IGFyZ3VtZW50IC4uLiB9XG5cbk9wdGlvbnM6XG4gIC1wLCAtLXBvcnQgPG51bWJlcj4gICBTZXQgbG9jYWwgcG9ydCBudW1iZXIgZm9yIGxvY2FsIG5ldFxuICAtbiwgLS1uZXQgPG5hbWU+ICAgICAgU2V0IGxvY2FsIG5ldCBuYW1lIHRvIHdoaWNoIGNvbW1hbmQgYXBwbGllZCwgY2FuIGJlIHNwZWNpZmllZCBtdWx0aXBsZSB0aW1lc1xuICAtaSwgLS1pbWFnZXMgICAgICAgICAgQXBwbHkgY29tbWFuZCBvbmx5IHRvIGRvY2tlciBpbWFnZXNcbiAgLWMsIC0tY29udGFpbmVycyAgICAgIEFwcGx5IGNvbW1hbmQgb25seSB0byBkb2NrZXIgY29udGFpbmVyc1xuICAtanMsIC0tSmF2YVNjcmlwdCAgICAgR2VuZXJhdGUgYWRkaXRpb25hbCBKYXZhU2NyaXB0IGNvZGVcbiAgXG4gICBcbkNvbW1hbmRzOlxuICBzb2wgPGZpbGVzPiAgIEJ1aWxkIFRPTiBjb250cmFjdCBmcm9tIHNvbGlkaXR5IHNvdXJjZSBjb2RlXG4gIHN0YXJ0ICAgICAgICAgU3RhcnQgbG9jYWwgbmV0IChpZiBuZXQgbmFtZSBkb2VzIG5vdCBzcGVjaWZpZWQgdGhlIGFsbCBuZXRzIHdpbGwgYmUgc3RhcnRlZClcbiAgc3RvcCAgICAgICAgICBTdG9wIGNvbXBpbGVycyBhbmQgYWxsIG5ldHMgICAgXG4gIGluZm8gICAgICAgICAgU2hvdyBjdXJyZW50IHN0YXR1cyBvZiBjb21waWxlcnMgYW5kIG5ldHNcbiAgc2V0dXAgICAgICAgICBMb29raW5nIGZvciBhIHJlcXVpcmVkIHByZXJlcXVpc2l0ZXMgYW5kIHNldHVwIHJlcXVpcmVkIGFkZGl0aW9uYWwgY29tcG9uZW50c1xuICBjbGVhbiAgICAgICAgIFJlbW92ZSBhbGwgVE9OIERldiBkb2NrZXIgY29udGFpbmVycyBhbmQgaW1hZ2VzXG4gIHVzZSA8dmVyc2lvbj4gU2VsZWN0IHZlcnNpb24gZm9yIGNvbXBpbGVycyBhbmQgbmV0cyBcbiAgICAgICAgXG5Db3B5cmlnaHQgMjAxOC0yMDIwIFRPTiBERVYgU09MVVRJT05TIExURC5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBTT0ZUV0FSRSBFVkFMVUFUSU9OIExpY2Vuc2UgKGh0dHBzOi8vd3d3LnRvbi5kZXYvbGljZW5zZXMpXG5gLFxuICAgIHRvbkRldkltYWdlcygpIHtcbiAgICAgICAgcmV0dXJuIGBJbWFnZXM6YDtcbiAgICB9LFxuICAgIHRvbkRldkNvbnRhaW5lcnMoKSB7XG4gICAgICAgIHJldHVybiBgQ29udGFpbmVyczpgO1xuICAgIH0sXG4gICAgbmV0SGVhZGVyKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGAke25hbWV9IG5ldHdvcmsvYmxvY2tjaGFpbjpgO1xuICAgIH0sXG4gICAgdXNlZFZlcnNpb24odmVyc2lvbikge1xuICAgICAgICByZXR1cm4gYCAgVXNlZCB2ZXJzaW9uOiAke3ZlcnNpb259YDtcbiAgICB9LFxuICAgIG5ldEhvc3RQb3J0KHBvcnQpIHtcbiAgICAgICAgcmV0dXJuIGAgIEJvdW5kIHRvIGhvc3QgcG9ydDogJHtwb3J0fWA7XG4gICAgfSxcbiAgICBuZXRBcmFuZ29Ib3N0UG9ydChwb3J0KSB7XG4gICAgICAgIHJldHVybiBgICBBcmFuZ28gREIgaXMgYm91bmQgdG8gaG9zdCBwb3J0OiAke3BvcnR9YDtcbiAgICB9LFxufTtcblxuZXhwb3J0IHsgdGV4dHMgfTtcbiJdfQ== -------------------------------------------------------------------------------- /dist/cli/info.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.infoCommand = infoCommand; 7 | 8 | var _compilers = require("../compilers/compilers"); 9 | 10 | var _dev = require("../dev"); 11 | 12 | var _networks = require("../networks/networks"); 13 | 14 | var _texts = require("../utils/texts"); 15 | 16 | var _utils = require("../utils/utils"); 17 | 18 | /* 19 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 20 | * 21 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 22 | * this file except in compliance with the License. You may obtain a copy of the 23 | * License at: https://www.ton.dev/licenses 24 | * 25 | * Unless required by applicable law or agreed to in writing, software 26 | * distributed under the License is distributed on an "AS IS" BASIS, 27 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 28 | * See the License for the specific TON DEV software governing permissions and 29 | * limitations under the License. 30 | * 31 | */ 32 | async function infoCommand(dev, options) { 33 | async function listTags(image) { 34 | const url = `https://registry.hub.docker.com/v2/repositories/${image}/tags/`; 35 | const tags = await (0, _utils.httpsGetJson)(url); 36 | return tags.results.map(x => x.name).sort(); 37 | } 38 | 39 | async function showAvailableVersions(imagePrefix) { 40 | console.log(` ${imagePrefix}: ${(await listTags(imagePrefix)).join(', ')}`); 41 | } 42 | 43 | function mapContainerName(name) { 44 | return name.startsWith('/') ? name.substr(1) : name; 45 | } 46 | 47 | async function showContainerInfo(name) { 48 | const info = await dev.docker.findContainerInfo(name); 49 | 50 | if (info) { 51 | console.log(` Docker image: ${info.Image}`); 52 | console.log(` Docker container: ${info.Names.map(mapContainerName).join(', ')} ${info.State}`); 53 | } else { 54 | console.log(` Docker container missing: ${name}`); 55 | } 56 | } 57 | 58 | console.log(_texts.texts.usageHeader(_utils.version)); 59 | 60 | for (let i = 0; i < dev.networks.length; i += 1) { 61 | const network = dev.networks[i]; 62 | console.log(); 63 | console.log(_texts.texts.netHeader(network.name)); 64 | console.log(); 65 | console.log(_texts.texts.usedVersion(network.version)); 66 | console.log(_texts.texts.netHostPort(network.hostPort)); 67 | 68 | if (network.arangoHostPort !== '') { 69 | console.log(_texts.texts.netArangoHostPort(network.arangoHostPort)); 70 | } 71 | 72 | await showContainerInfo(network.containerName); 73 | } 74 | 75 | console.log(); 76 | console.log(_texts.texts.compilerHeader); 77 | console.log(); 78 | console.log(_texts.texts.usedVersion(dev.compilers.version)); 79 | await showContainerInfo(dev.compilers.containerName); 80 | 81 | if (options.available) { 82 | console.log(); 83 | console.log(_texts.texts.availableVersions); 84 | console.log(); 85 | await showAvailableVersions(_compilers.Compilers.imagePrefix); 86 | await showAvailableVersions(_networks.Network.imagePrefix); 87 | } 88 | } 89 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvaW5mby5qcyJdLCJuYW1lcyI6WyJpbmZvQ29tbWFuZCIsImRldiIsIm9wdGlvbnMiLCJsaXN0VGFncyIsImltYWdlIiwidXJsIiwidGFncyIsInJlc3VsdHMiLCJtYXAiLCJ4IiwibmFtZSIsInNvcnQiLCJzaG93QXZhaWxhYmxlVmVyc2lvbnMiLCJpbWFnZVByZWZpeCIsImNvbnNvbGUiLCJsb2ciLCJqb2luIiwibWFwQ29udGFpbmVyTmFtZSIsInN0YXJ0c1dpdGgiLCJzdWJzdHIiLCJzaG93Q29udGFpbmVySW5mbyIsImluZm8iLCJkb2NrZXIiLCJmaW5kQ29udGFpbmVySW5mbyIsIkltYWdlIiwiTmFtZXMiLCJTdGF0ZSIsInRleHRzIiwidXNhZ2VIZWFkZXIiLCJ2ZXJzaW9uIiwiaSIsIm5ldHdvcmtzIiwibGVuZ3RoIiwibmV0d29yayIsIm5ldEhlYWRlciIsInVzZWRWZXJzaW9uIiwibmV0SG9zdFBvcnQiLCJob3N0UG9ydCIsImFyYW5nb0hvc3RQb3J0IiwibmV0QXJhbmdvSG9zdFBvcnQiLCJjb250YWluZXJOYW1lIiwiY29tcGlsZXJIZWFkZXIiLCJjb21waWxlcnMiLCJhdmFpbGFibGUiLCJhdmFpbGFibGVWZXJzaW9ucyIsIkNvbXBpbGVycyIsIk5ldHdvcmsiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFpQkE7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBdEJBOzs7Ozs7Ozs7Ozs7OztBQXlCTyxlQUFlQSxXQUFmLENBQTJCQyxHQUEzQixFQUFxQ0MsT0FBckMsRUFBMkQ7QUFDOUQsaUJBQWVDLFFBQWYsQ0FBd0JDLEtBQXhCLEVBQTBEO0FBQ3RELFVBQU1DLEdBQUcsR0FBSSxtREFBa0RELEtBQU0sUUFBckU7QUFDQSxVQUFNRSxJQUFJLEdBQUcsTUFBTSx5QkFBYUQsR0FBYixDQUFuQjtBQUNBLFdBQU9DLElBQUksQ0FBQ0MsT0FBTCxDQUFhQyxHQUFiLENBQWlCQyxDQUFDLElBQUlBLENBQUMsQ0FBQ0MsSUFBeEIsRUFBOEJDLElBQTlCLEVBQVA7QUFDSDs7QUFFRCxpQkFBZUMscUJBQWYsQ0FBcUNDLFdBQXJDLEVBQTBEO0FBQ3REQyxJQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBYSxLQUFJRixXQUFZLEtBQUksQ0FBQyxNQUFNVixRQUFRLENBQUNVLFdBQUQsQ0FBZixFQUE4QkcsSUFBOUIsQ0FBbUMsSUFBbkMsQ0FBeUMsRUFBMUU7QUFDSDs7QUFFRCxXQUFTQyxnQkFBVCxDQUEwQlAsSUFBMUIsRUFBZ0Q7QUFDNUMsV0FBT0EsSUFBSSxDQUFDUSxVQUFMLENBQWdCLEdBQWhCLElBQXVCUixJQUFJLENBQUNTLE1BQUwsQ0FBWSxDQUFaLENBQXZCLEdBQXdDVCxJQUEvQztBQUNIOztBQUVELGlCQUFlVSxpQkFBZixDQUFpQ1YsSUFBakMsRUFBK0M7QUFDM0MsVUFBTVcsSUFBcUIsR0FBRyxNQUFNcEIsR0FBRyxDQUFDcUIsTUFBSixDQUFXQyxpQkFBWCxDQUE2QmIsSUFBN0IsQ0FBcEM7O0FBQ0EsUUFBSVcsSUFBSixFQUFVO0FBQ05QLE1BQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFhLG1CQUFrQk0sSUFBSSxDQUFDRyxLQUFNLEVBQTFDO0FBQ0FWLE1BQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFhLHVCQUFzQk0sSUFBSSxDQUFDSSxLQUFMLENBQVdqQixHQUFYLENBQWVTLGdCQUFmLEVBQWlDRCxJQUFqQyxDQUFzQyxJQUF0QyxDQUE0QyxJQUFHSyxJQUFJLENBQUNLLEtBQU0sRUFBN0Y7QUFDSCxLQUhELE1BR087QUFDSFosTUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQWEsK0JBQThCTCxJQUFLLEVBQWhEO0FBQ0g7QUFDSjs7QUFFREksRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVlZLGFBQU1DLFdBQU4sQ0FBa0JDLGNBQWxCLENBQVo7O0FBRUEsT0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHN0IsR0FBRyxDQUFDOEIsUUFBSixDQUFhQyxNQUFqQyxFQUF5Q0YsQ0FBQyxJQUFJLENBQTlDLEVBQWlEO0FBQzdDLFVBQU1HLE9BQU8sR0FBR2hDLEdBQUcsQ0FBQzhCLFFBQUosQ0FBYUQsQ0FBYixDQUFoQjtBQUNBaEIsSUFBQUEsT0FBTyxDQUFDQyxHQUFSO0FBQ0FELElBQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZWSxhQUFNTyxTQUFOLENBQWdCRCxPQUFPLENBQUN2QixJQUF4QixDQUFaO0FBQ0FJLElBQUFBLE9BQU8sQ0FBQ0MsR0FBUjtBQUNBRCxJQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWVksYUFBTVEsV0FBTixDQUFrQkYsT0FBTyxDQUFDSixPQUExQixDQUFaO0FBQ0FmLElBQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZWSxhQUFNUyxXQUFOLENBQWtCSCxPQUFPLENBQUNJLFFBQTFCLENBQVo7O0FBQ0EsUUFBSUosT0FBTyxDQUFDSyxjQUFSLEtBQTJCLEVBQS9CLEVBQW1DO0FBQy9CeEIsTUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVlZLGFBQU1ZLGlCQUFOLENBQXdCTixPQUFPLENBQUNLLGNBQWhDLENBQVo7QUFDSDs7QUFDRCxVQUFNbEIsaUJBQWlCLENBQUNhLE9BQU8sQ0FBQ08sYUFBVCxDQUF2QjtBQUNIOztBQUNEMUIsRUFBQUEsT0FBTyxDQUFDQyxHQUFSO0FBQ0FELEVBQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZWSxhQUFNYyxjQUFsQjtBQUNBM0IsRUFBQUEsT0FBTyxDQUFDQyxHQUFSO0FBQ0FELEVBQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZWSxhQUFNUSxXQUFOLENBQWtCbEMsR0FBRyxDQUFDeUMsU0FBSixDQUFjYixPQUFoQyxDQUFaO0FBQ0EsUUFBTVQsaUJBQWlCLENBQUNuQixHQUFHLENBQUN5QyxTQUFKLENBQWNGLGFBQWYsQ0FBdkI7O0FBR0EsTUFBSXRDLE9BQU8sQ0FBQ3lDLFNBQVosRUFBdUI7QUFDbkI3QixJQUFBQSxPQUFPLENBQUNDLEdBQVI7QUFDQUQsSUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVlZLGFBQU1pQixpQkFBbEI7QUFDQTlCLElBQUFBLE9BQU8sQ0FBQ0MsR0FBUjtBQUNBLFVBQU1ILHFCQUFxQixDQUFDaUMscUJBQVVoQyxXQUFYLENBQTNCO0FBQ0EsVUFBTUQscUJBQXFCLENBQUNrQyxrQkFBUWpDLFdBQVQsQ0FBM0I7QUFDSDtBQUNKIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAyMDE4LTIwMjAgVE9OIERFViBTT0xVVElPTlMgTFRELlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBTT0ZUV0FSRSBFVkFMVUFUSU9OIExpY2Vuc2UgKHRoZSBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZVxuICogdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlXG4gKiBMaWNlbnNlIGF0OiBodHRwczovL3d3dy50b24uZGV2L2xpY2Vuc2VzXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBUT04gREVWIHNvZnR3YXJlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuLy8gQGZsb3dcblxuXG5pbXBvcnQgeyBDb21waWxlcnMgfSBmcm9tIFwiLi4vY29tcGlsZXJzL2NvbXBpbGVyc1wiO1xuaW1wb3J0IHsgRGV2IH0gZnJvbSBcIi4uL2RldlwiO1xuaW1wb3J0IHsgTmV0d29yayB9IGZyb20gXCIuLi9uZXR3b3Jrcy9uZXR3b3Jrc1wiO1xuaW1wb3J0IHR5cGUgeyBEQ29udGFpbmVySW5mbyB9IGZyb20gXCIuLi91dGlscy9kb2NrZXJcIjtcbmltcG9ydCB7IHRleHRzIH0gZnJvbSBcIi4uL3V0aWxzL3RleHRzXCI7XG5pbXBvcnQgeyBodHRwc0dldEpzb24sIHZlcnNpb24gfSBmcm9tIFwiLi4vdXRpbHMvdXRpbHNcIjtcbmltcG9ydCB0eXBlIHsgSW5mb09wdGlvbnMgfSBmcm9tIFwiLi9vcHRpb25zXCI7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpbmZvQ29tbWFuZChkZXY6IERldiwgb3B0aW9uczogSW5mb09wdGlvbnMpIHtcbiAgICBhc3luYyBmdW5jdGlvbiBsaXN0VGFncyhpbWFnZTogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgICAgICBjb25zdCB1cmwgPSBgaHR0cHM6Ly9yZWdpc3RyeS5odWIuZG9ja2VyLmNvbS92Mi9yZXBvc2l0b3JpZXMvJHtpbWFnZX0vdGFncy9gO1xuICAgICAgICBjb25zdCB0YWdzID0gYXdhaXQgaHR0cHNHZXRKc29uKHVybCk7XG4gICAgICAgIHJldHVybiB0YWdzLnJlc3VsdHMubWFwKHggPT4geC5uYW1lKS5zb3J0KCk7XG4gICAgfVxuXG4gICAgYXN5bmMgZnVuY3Rpb24gc2hvd0F2YWlsYWJsZVZlcnNpb25zKGltYWdlUHJlZml4OiBzdHJpbmcpIHtcbiAgICAgICAgY29uc29sZS5sb2coYCAgJHtpbWFnZVByZWZpeH06ICR7KGF3YWl0IGxpc3RUYWdzKGltYWdlUHJlZml4KSkuam9pbignLCAnKX1gKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXBDb250YWluZXJOYW1lKG5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBuYW1lLnN0YXJ0c1dpdGgoJy8nKSA/IG5hbWUuc3Vic3RyKDEpIDogbmFtZTtcbiAgICB9XG5cbiAgICBhc3luYyBmdW5jdGlvbiBzaG93Q29udGFpbmVySW5mbyhuYW1lOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgaW5mbzogP0RDb250YWluZXJJbmZvID0gYXdhaXQgZGV2LmRvY2tlci5maW5kQ29udGFpbmVySW5mbyhuYW1lKTtcbiAgICAgICAgaWYgKGluZm8pIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGAgIERvY2tlciBpbWFnZTogJHtpbmZvLkltYWdlfWApO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYCAgRG9ja2VyIGNvbnRhaW5lcjogJHtpbmZvLk5hbWVzLm1hcChtYXBDb250YWluZXJOYW1lKS5qb2luKCcsICcpfSAke2luZm8uU3RhdGV9YCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgICBEb2NrZXIgY29udGFpbmVyIG1pc3Npbmc6ICR7bmFtZX1gKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKHRleHRzLnVzYWdlSGVhZGVyKHZlcnNpb24pKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGV2Lm5ldHdvcmtzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIGNvbnN0IG5ldHdvcmsgPSBkZXYubmV0d29ya3NbaV07XG4gICAgICAgIGNvbnNvbGUubG9nKCk7XG4gICAgICAgIGNvbnNvbGUubG9nKHRleHRzLm5ldEhlYWRlcihuZXR3b3JrLm5hbWUpKTtcbiAgICAgICAgY29uc29sZS5sb2coKTtcbiAgICAgICAgY29uc29sZS5sb2codGV4dHMudXNlZFZlcnNpb24obmV0d29yay52ZXJzaW9uKSk7XG4gICAgICAgIGNvbnNvbGUubG9nKHRleHRzLm5ldEhvc3RQb3J0KG5ldHdvcmsuaG9zdFBvcnQpKTtcbiAgICAgICAgaWYgKG5ldHdvcmsuYXJhbmdvSG9zdFBvcnQgIT09ICcnKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0ZXh0cy5uZXRBcmFuZ29Ib3N0UG9ydChuZXR3b3JrLmFyYW5nb0hvc3RQb3J0KSk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgc2hvd0NvbnRhaW5lckluZm8obmV0d29yay5jb250YWluZXJOYW1lKTtcbiAgICB9XG4gICAgY29uc29sZS5sb2coKTtcbiAgICBjb25zb2xlLmxvZyh0ZXh0cy5jb21waWxlckhlYWRlcik7XG4gICAgY29uc29sZS5sb2coKTtcbiAgICBjb25zb2xlLmxvZyh0ZXh0cy51c2VkVmVyc2lvbihkZXYuY29tcGlsZXJzLnZlcnNpb24pKTtcbiAgICBhd2FpdCBzaG93Q29udGFpbmVySW5mbyhkZXYuY29tcGlsZXJzLmNvbnRhaW5lck5hbWUpO1xuXG5cbiAgICBpZiAob3B0aW9ucy5hdmFpbGFibGUpIHtcbiAgICAgICAgY29uc29sZS5sb2coKTtcbiAgICAgICAgY29uc29sZS5sb2codGV4dHMuYXZhaWxhYmxlVmVyc2lvbnMpO1xuICAgICAgICBjb25zb2xlLmxvZygpO1xuICAgICAgICBhd2FpdCBzaG93QXZhaWxhYmxlVmVyc2lvbnMoQ29tcGlsZXJzLmltYWdlUHJlZml4KTtcbiAgICAgICAgYXdhaXQgc2hvd0F2YWlsYWJsZVZlcnNpb25zKE5ldHdvcmsuaW1hZ2VQcmVmaXgpO1xuICAgIH1cbn1cbiJdfQ== -------------------------------------------------------------------------------- /src/dev.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | // @flow 16 | 17 | import { Compilers } from "./compilers/compilers"; 18 | import type { CompilersConfig } from "./compilers/compilers"; 19 | import type { NetworkConfig } from "./networks/networks"; 20 | import { Network } from "./networks/networks"; 21 | import type { ContainerDef, DContainerInfo, DImageInfo, DMount, DockerContainer } from "./utils/docker"; 22 | import { ContainerStatus, DevDocker } from "./utils/docker"; 23 | import { texts } from "./utils/texts"; 24 | import type { PathJoin } from "./utils/utils"; 25 | import { bindPathJoinTo, breakWords, inputLine, tonlabsHomePath, version } from "./utils/utils"; 26 | 27 | const fs = require('fs'); 28 | const os = require('os'); 29 | const path = require('path'); 30 | 31 | type DevConfig = { 32 | compilers: CompilersConfig, 33 | networks: NetworkConfig[], 34 | }; 35 | 36 | export type CompilersWithNetworks = { 37 | compilers: boolean, 38 | networks: Network[], 39 | } 40 | 41 | function excludeCompilers(dev: Dev, defs: ContainerDef[]): ContainerDef[] { 42 | return defs.filter(x => x !== dev.compilers); 43 | } 44 | 45 | class Dev { 46 | static defaultConfig: DevConfig = Object.freeze({ 47 | compilers: Compilers.defaultConfig, 48 | networks: [Network.defaultConfig], 49 | }); 50 | name: string; 51 | version: string; 52 | docker: DevDocker; 53 | networks: Network[]; 54 | compilers: Compilers; 55 | agreementRequired: boolean; 56 | configFilePath: string; 57 | 58 | constructor() { 59 | this.name = 'tondev'; 60 | this.version = version; 61 | this.agreementRequired = true; 62 | this.docker = new DevDocker(); 63 | this.docker.onStartupImages = this.onStartupImages; 64 | this.docker.onBeforePull = this.onBeforePull; 65 | this.compilers = new Compilers(Compilers.defaultConfig); 66 | this.networks = [new Network(Network.defaultConfig)]; 67 | this.configFilePath = tonlabsHomePath('config.json'); 68 | fs.mkdirSync(tonlabsHomePath(), ({ recursive: true }: any)); 69 | this.loadConfig(); 70 | } 71 | 72 | loadConfig() { 73 | try { 74 | const config: DevConfig = JSON.parse(fs.readFileSync(this.configFilePath, { encoding: 'utf8' })); 75 | this.compilers.setConfig(config.compilers); 76 | this.networks = config.networks.map(x => new Network(x)); 77 | } catch { 78 | } 79 | 80 | } 81 | 82 | saveConfig() { 83 | const config: DevConfig = { 84 | compilers: this.compilers.getConfig(), 85 | networks: this.networks.map(x => x.getConfig()), 86 | }; 87 | fs.mkdirSync(tonlabsHomePath(''), ({ recursive: true }: any)); 88 | fs.writeFileSync(this.configFilePath, JSON.stringify(config), { encoding: 'utf8' }); 89 | } 90 | 91 | onStartupImages = (images: DImageInfo[]) => { 92 | this.agreementRequired = !images.find(Dev.isDevImage); 93 | }; 94 | 95 | onBeforePull = async (_repoTag: string): Promise => { 96 | if (!this.agreementRequired) { 97 | return; 98 | } 99 | const license = fs 100 | .readFileSync(path.join(__dirname, '..', 'LICENSE')) 101 | .toString() 102 | .split('\n') 103 | .map(breakWords).join('\n'); 104 | console.log(license); 105 | process.stdout.write(texts.agreementConfirmation); 106 | const answer = (await inputLine()).trim().toLowerCase(); 107 | if (answer !== 'yes') { 108 | console.log(texts.agreementRejected); 109 | process.exit(0); 110 | } 111 | console.log(texts.agreementAccepted); 112 | this.agreementRequired = false; 113 | }; 114 | 115 | networksFromNames(names: string[]): Network[] { 116 | return names.map((name) => { 117 | const network = this.networks.find(x => x.name.toLowerCase() === name.toLowerCase()); 118 | if (!network) { 119 | throw new Error(`Network not found: ${name}`) 120 | } 121 | return network; 122 | }); 123 | } 124 | 125 | networksOrAll(names: string[]): Network[] { 126 | return names.length > 0 ? this.networksFromNames(names) : this.networks; 127 | } 128 | 129 | getDefs(source: CompilersWithNetworks): ContainerDef[] { 130 | return source.compilers ? source.networks.concat(this.compilers) : [...source.networks]; 131 | } 132 | 133 | async start(source: CompilersWithNetworks) { 134 | await this.docker.startupContainers(excludeCompilers(this, this.getDefs(source)), ContainerStatus.running); 135 | } 136 | 137 | async stop(source: CompilersWithNetworks) { 138 | await this.docker.shutdownContainers(this.getDefs(source), ContainerStatus.created); 139 | } 140 | 141 | async restart(source: CompilersWithNetworks) { 142 | const defs = this.getDefs(source); 143 | await this.docker.shutdownContainers(defs, ContainerStatus.created); 144 | await this.docker.startupContainers(excludeCompilers(this, defs), ContainerStatus.running); 145 | } 146 | 147 | async recreate(source: CompilersWithNetworks) { 148 | const defs = this.getDefs(source); 149 | await this.docker.shutdownContainers(defs, ContainerStatus.missing); 150 | await this.docker.startupContainers(excludeCompilers(this, defs), ContainerStatus.created); 151 | } 152 | 153 | 154 | async clean(compilers: boolean, networks: boolean, containersOnly: boolean) { 155 | const imageMatches = []; 156 | if (compilers) { 157 | imageMatches.push(Compilers.imagePrefix); 158 | } 159 | if (networks) { 160 | imageMatches.push(Network.imagePrefix); 161 | } 162 | await this.docker.removeImages(imageMatches, containersOnly); 163 | } 164 | 165 | async useVersion(version: string, source: CompilersWithNetworks) { 166 | const defs = this.getDefs(source); 167 | await this.docker.shutdownContainers(defs, ContainerStatus.missing); 168 | if (source.compilers) { 169 | this.compilers.setConfig({ 170 | ...this.compilers.getConfig(), 171 | version 172 | }); 173 | } 174 | source.networks.forEach((network) => { 175 | const config = network.getConfig(); 176 | config.version = version; 177 | network.setConfig(config); 178 | }); 179 | this.saveConfig(); 180 | await this.docker.startupContainers(excludeCompilers(this, defs), ContainerStatus.running); 181 | } 182 | 183 | // Compilers 184 | 185 | hostPathToMountSource(hostPath: string): string { 186 | if (os.platform() !== 'win32') { 187 | return hostPath.toLowerCase(); 188 | } 189 | return `/host_mnt/${hostPath.replace(/:\\|\\/g, '/').toLowerCase()}`; 190 | } 191 | 192 | async getCompilersMountedTo(hostPath: string): Promise<{container: DockerContainer, guestPath: PathJoin}> { 193 | let info = (await this.docker.getContainerInfos()).find((info: DContainerInfo) => { 194 | return DevDocker.containersImageMatched(info, this.compilers.requiredImage) 195 | && info.Mounts.find((mount: DMount) => mount.Source.toLowerCase() === this.hostPathToMountSource(hostPath)); 196 | }); 197 | let container: DockerContainer; 198 | if (info) { 199 | container = this.docker.client.getContainer(info.Id); 200 | if (!DevDocker.isRunning(info)) { 201 | await container.start(); 202 | } 203 | } else { 204 | container = await this.compilers.createContainerMountedTo(hostPath, this.docker); 205 | await container.start(); 206 | } 207 | return { 208 | container, 209 | guestPath: bindPathJoinTo(this.compilers.mountDestination, '/') 210 | }; 211 | } 212 | 213 | // Networks 214 | 215 | ensureNetwork(name: string): Network { 216 | const existing = this.networks.find(x => x.name.toLowerCase() === name.toLowerCase()); 217 | if (existing) { 218 | return existing; 219 | } 220 | const network = new Network({ 221 | ...Network.defaultConfig, 222 | name 223 | }); 224 | this.networks.push(network); 225 | return network; 226 | } 227 | 228 | checkUniqueName(name: string) { 229 | if (this.networks.find(x => x.name.toLowerCase() === name.toLowerCase())) { 230 | throw new Error(`Network with name [${name}] already exists`); 231 | } 232 | } 233 | 234 | addNetworks(names: string[]) { 235 | names.forEach((name) => { 236 | this.checkUniqueName(name); 237 | const network = new Network({ 238 | ...Network.defaultConfig, 239 | name 240 | }); 241 | this.networks.push(network); 242 | }); 243 | this.saveConfig(); 244 | } 245 | 246 | 247 | async removeNetworks(networks: Network[]) { 248 | await this.docker.shutdownContainers(networks, ContainerStatus.missing); 249 | networks.forEach((network) => { 250 | const index = this.networks.findIndex(x => x === network); 251 | if (index >= 0) { 252 | this.networks.splice(index, 1); 253 | } 254 | }); 255 | this.saveConfig(); 256 | } 257 | 258 | 259 | async updateNetworkConfigs(networks: Network[], update: (config: NetworkConfig) => void) { 260 | const defs = [...networks]; 261 | await this.docker.shutdownContainers(defs, ContainerStatus.missing); 262 | networks.forEach((network) => { 263 | const config = network.getConfig(); 264 | const saveName = config.name; 265 | update(config); 266 | if (config.name.toLowerCase() !== saveName.toLowerCase()) { 267 | this.checkUniqueName(config.name); 268 | } 269 | network.setConfig(config) 270 | }); 271 | this.saveConfig(); 272 | await this.docker.startupContainers(defs, ContainerStatus.running); 273 | } 274 | 275 | static isDevContainer(info: DContainerInfo): boolean { 276 | return DevDocker.containersImageMatched(info, Compilers.imagePrefix) 277 | || DevDocker.containersImageMatched(info, Network.imagePrefix); 278 | } 279 | 280 | static isDevImage(info: DImageInfo): boolean { 281 | return DevDocker.imageHasMatchedName(info, Compilers.imagePrefix) 282 | || DevDocker.imageHasMatchedName(info, Network.imagePrefix); 283 | } 284 | } 285 | 286 | export { Dev }; 287 | -------------------------------------------------------------------------------- /dist/cli/spy.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.spy = spy; 7 | 8 | var _dev = require("../dev"); 9 | 10 | var _networks = require("../networks/networks"); 11 | 12 | var _texts = require("../utils/texts"); 13 | 14 | var _utils = require("../utils/utils"); 15 | 16 | /* 17 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 18 | * 19 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 20 | * this file except in compliance with the License. You may obtain a copy of the 21 | * License at: https://www.ton.dev/licenses 22 | * 23 | * Unless required by applicable law or agreed to in writing, software 24 | * distributed under the License is distributed on an "AS IS" BASIS, 25 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26 | * See the License for the specific TON DEV software governing permissions and 27 | * limitations under the License. 28 | * 29 | */ 30 | //TODO: import { TONClient } from "ton-client-node-js"; 31 | async function createClient(netAddress) { 32 | return {}; //TODO: return TONClient.create({ 33 | // servers: [netAddress] 34 | // }); 35 | } 36 | 37 | const transactionProjection = ` 38 | id 39 | account_addr 40 | in_message { 41 | header { 42 | ...on MessageHeaderExtOutMsgInfoVariant { 43 | ExtOutMsgInfo { 44 | dst { 45 | ...on MsgAddressExtAddrNoneVariant { AddrNone { None } } 46 | ...on MsgAddressExtAddrExternVariant { AddrExtern { AddrExtern } } 47 | } 48 | } 49 | } 50 | ...on MessageHeaderExtInMsgInfoVariant { 51 | ExtInMsgInfo { 52 | src { 53 | ...on MsgAddressExtAddrExternVariant { AddrExtern { AddrExtern } } 54 | ...on MsgAddressExtAddrNoneVariant { AddrNone { None } } 55 | } 56 | } 57 | } 58 | ...on MessageHeaderIntMsgInfoVariant { 59 | IntMsgInfo { 60 | value { Grams } 61 | src { 62 | ...on MsgAddressIntAddrVarVariant { AddrVar { address } } 63 | ...on MsgAddressIntAddrStdVariant { AddrStd { address } } 64 | ...on MsgAddressIntAddrNoneVariant { AddrNone { None } } 65 | } 66 | } 67 | } 68 | } 69 | } 70 | `; 71 | 72 | async function spy(dev, names) { 73 | console.log(_texts.texts.usageHeader(_utils.version)); 74 | await Promise.all(dev.networks.map(async net => { 75 | const netAddress = `http://0.0.0.0:${net.hostPort || '80'}`; 76 | console.log(`Spy for ${net.name} at ${netAddress}`); 77 | const localNet = await createClient(netAddress); 78 | const accounts = await localNet.queries.accounts.query({}, 'id', [{ 79 | path: 'id', 80 | direction: 'ASC' 81 | }], 11); 82 | console.log('Accounts:'); 83 | accounts.slice(0, 10).forEach(x => console.log(` ${x.id}`)); 84 | 85 | if (accounts.length > 10) { 86 | console.log(' and more...'); 87 | } 88 | 89 | console.log(''); 90 | console.log('Looking for transactions and more... Press [Enter] to stop...'); 91 | localNet.queries.transactions.subscribe({}, transactionProjection, (e, tr) => { 92 | console.log('TRX:', tr.id); 93 | const msg = tr.in_message; 94 | const intMsg = msg.header.IntMsgInfo; 95 | 96 | if (intMsg) { 97 | console.log(' ', `${tr.account_addr} <- ${intMsg.value.Grams} <- ${intMsg.src.AddrStd.address}`); 98 | } else { 99 | console.log(' ', `${tr.account_addr} <- EXT`); 100 | } 101 | }); 102 | localNet.queries.accounts.subscribe({}, 'id', (e, d) => { 103 | console.log('ACC:', d.id); 104 | }); 105 | })); 106 | await (0, _utils.inputLine)(); 107 | } 108 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvc3B5LmpzIl0sIm5hbWVzIjpbImNyZWF0ZUNsaWVudCIsIm5ldEFkZHJlc3MiLCJ0cmFuc2FjdGlvblByb2plY3Rpb24iLCJzcHkiLCJkZXYiLCJuYW1lcyIsImNvbnNvbGUiLCJsb2ciLCJ0ZXh0cyIsInVzYWdlSGVhZGVyIiwidmVyc2lvbiIsIlByb21pc2UiLCJhbGwiLCJuZXR3b3JrcyIsIm1hcCIsIm5ldCIsImhvc3RQb3J0IiwibmFtZSIsImxvY2FsTmV0IiwiYWNjb3VudHMiLCJxdWVyaWVzIiwicXVlcnkiLCJwYXRoIiwiZGlyZWN0aW9uIiwic2xpY2UiLCJmb3JFYWNoIiwieCIsImlkIiwibGVuZ3RoIiwidHJhbnNhY3Rpb25zIiwic3Vic2NyaWJlIiwiZSIsInRyIiwibXNnIiwiaW5fbWVzc2FnZSIsImludE1zZyIsImhlYWRlciIsIkludE1zZ0luZm8iLCJhY2NvdW50X2FkZHIiLCJ2YWx1ZSIsIkdyYW1zIiwic3JjIiwiQWRkclN0ZCIsImFkZHJlc3MiLCJkIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBaUJBOztBQUNBOztBQUNBOztBQUNBOztBQXBCQTs7Ozs7Ozs7Ozs7Ozs7QUFnQkE7QUFNQSxlQUFlQSxZQUFmLENBQTRCQyxVQUE1QixFQUFnRDtBQUM1QyxTQUFPLEVBQVAsQ0FENEMsQ0FFNUM7QUFDQTtBQUNBO0FBQ0g7O0FBRUQsTUFBTUMscUJBQXFCLEdBQUk7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztDQUEvQjs7QUFtQ0EsZUFBZUMsR0FBZixDQUFtQkMsR0FBbkIsRUFBNkJDLEtBQTdCLEVBQThDO0FBQzFDQyxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWUMsYUFBTUMsV0FBTixDQUFrQkMsY0FBbEIsQ0FBWjtBQUNBLFFBQU1DLE9BQU8sQ0FBQ0MsR0FBUixDQUFZUixHQUFHLENBQUNTLFFBQUosQ0FBYUMsR0FBYixDQUFpQixNQUFPQyxHQUFQLElBQXdCO0FBQ3ZELFVBQU1kLFVBQVUsR0FBSSxrQkFBaUJjLEdBQUcsQ0FBQ0MsUUFBSixJQUFnQixJQUFLLEVBQTFEO0FBQ0FWLElBQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFhLFdBQVVRLEdBQUcsQ0FBQ0UsSUFBSyxPQUFNaEIsVUFBVyxFQUFqRDtBQUNBLFVBQU1pQixRQUFRLEdBQUcsTUFBTWxCLFlBQVksQ0FBQ0MsVUFBRCxDQUFuQztBQUNBLFVBQU1rQixRQUFRLEdBQUcsTUFBTUQsUUFBUSxDQUFDRSxPQUFULENBQWlCRCxRQUFqQixDQUEwQkUsS0FBMUIsQ0FBZ0MsRUFBaEMsRUFBb0MsSUFBcEMsRUFBMEMsQ0FBQztBQUFFQyxNQUFBQSxJQUFJLEVBQUUsSUFBUjtBQUFjQyxNQUFBQSxTQUFTLEVBQUU7QUFBekIsS0FBRCxDQUExQyxFQUE4RSxFQUE5RSxDQUF2QjtBQUNBakIsSUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksV0FBWjtBQUNBWSxJQUFBQSxRQUFRLENBQUNLLEtBQVQsQ0FBZSxDQUFmLEVBQWtCLEVBQWxCLEVBQXNCQyxPQUF0QixDQUE4QkMsQ0FBQyxJQUFJcEIsT0FBTyxDQUFDQyxHQUFSLENBQWEsS0FBSW1CLENBQUMsQ0FBQ0MsRUFBRyxFQUF0QixDQUFuQzs7QUFDQSxRQUFJUixRQUFRLENBQUNTLE1BQVQsR0FBa0IsRUFBdEIsRUFBMEI7QUFDdEJ0QixNQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSxlQUFaO0FBQ0g7O0FBQ0RELElBQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZLEVBQVo7QUFDQUQsSUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksK0RBQVo7QUFDQVcsSUFBQUEsUUFBUSxDQUFDRSxPQUFULENBQWlCUyxZQUFqQixDQUE4QkMsU0FBOUIsQ0FBd0MsRUFBeEMsRUFBNEM1QixxQkFBNUMsRUFBbUUsQ0FBQzZCLENBQUQsRUFBSUMsRUFBSixLQUFXO0FBQzFFMUIsTUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksTUFBWixFQUFvQnlCLEVBQUUsQ0FBQ0wsRUFBdkI7QUFDQSxZQUFNTSxHQUFHLEdBQUdELEVBQUUsQ0FBQ0UsVUFBZjtBQUNBLFlBQU1DLE1BQU0sR0FBR0YsR0FBRyxDQUFDRyxNQUFKLENBQVdDLFVBQTFCOztBQUNBLFVBQUlGLE1BQUosRUFBWTtBQUNSN0IsUUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksTUFBWixFQUFxQixHQUFFeUIsRUFBRSxDQUFDTSxZQUFhLE9BQU1ILE1BQU0sQ0FBQ0ksS0FBUCxDQUFhQyxLQUFNLE9BQU1MLE1BQU0sQ0FBQ00sR0FBUCxDQUFXQyxPQUFYLENBQW1CQyxPQUFRLEVBQWpHO0FBQ0gsT0FGRCxNQUVPO0FBQ0hyQyxRQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSxNQUFaLEVBQXFCLEdBQUV5QixFQUFFLENBQUNNLFlBQWEsU0FBdkM7QUFDSDtBQUNKLEtBVEQ7QUFVQXBCLElBQUFBLFFBQVEsQ0FBQ0UsT0FBVCxDQUFpQkQsUUFBakIsQ0FBMEJXLFNBQTFCLENBQW9DLEVBQXBDLEVBQXdDLElBQXhDLEVBQThDLENBQUNDLENBQUQsRUFBSWEsQ0FBSixLQUFVO0FBQ3BEdEMsTUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksTUFBWixFQUFvQnFDLENBQUMsQ0FBQ2pCLEVBQXRCO0FBQ0gsS0FGRDtBQUdILEdBekJpQixDQUFaLENBQU47QUEyQkEsUUFBTSx1QkFBTjtBQUNIIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAyMDE4LTIwMjAgVE9OIERFViBTT0xVVElPTlMgTFRELlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBTT0ZUV0FSRSBFVkFMVUFUSU9OIExpY2Vuc2UgKHRoZSBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZVxuICogdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlXG4gKiBMaWNlbnNlIGF0OiBodHRwczovL3d3dy50b24uZGV2L2xpY2Vuc2VzXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBUT04gREVWIHNvZnR3YXJlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuLy8gQGZsb3dcblxuLy9UT0RPOiBpbXBvcnQgeyBUT05DbGllbnQgfSBmcm9tIFwidG9uLWNsaWVudC1ub2RlLWpzXCI7XG5pbXBvcnQgeyBEZXYgfSBmcm9tIFwiLi4vZGV2XCI7XG5pbXBvcnQgeyBOZXR3b3JrIH0gZnJvbSBcIi4uL25ldHdvcmtzL25ldHdvcmtzXCI7XG5pbXBvcnQgeyB0ZXh0cyB9IGZyb20gXCIuLi91dGlscy90ZXh0c1wiO1xuaW1wb3J0IHsgaW5wdXRMaW5lLCB2ZXJzaW9uIH0gZnJvbSBcIi4uL3V0aWxzL3V0aWxzXCI7XG5cbmFzeW5jIGZ1bmN0aW9uIGNyZWF0ZUNsaWVudChuZXRBZGRyZXNzOiBzdHJpbmcpIHtcbiAgICByZXR1cm4ge307XG4gICAgLy9UT0RPOiByZXR1cm4gVE9OQ2xpZW50LmNyZWF0ZSh7XG4gICAgLy8gICAgIHNlcnZlcnM6IFtuZXRBZGRyZXNzXVxuICAgIC8vIH0pO1xufVxuXG5jb25zdCB0cmFuc2FjdGlvblByb2plY3Rpb24gPSBgXG4gICAgaWRcbiAgICBhY2NvdW50X2FkZHJcbiAgICBpbl9tZXNzYWdlIHtcbiAgICAgIGhlYWRlciB7XG4gICAgICAgIC4uLm9uIE1lc3NhZ2VIZWFkZXJFeHRPdXRNc2dJbmZvVmFyaWFudCB7XG4gICAgICAgICAgRXh0T3V0TXNnSW5mbyB7XG4gICAgICAgICAgICBkc3Qge1xuICAgICAgICAgICAgICAuLi5vbiBNc2dBZGRyZXNzRXh0QWRkck5vbmVWYXJpYW50IHsgQWRkck5vbmUgeyBOb25lIH0gfVxuICAgICAgICAgICAgICAuLi5vbiBNc2dBZGRyZXNzRXh0QWRkckV4dGVyblZhcmlhbnQgeyBBZGRyRXh0ZXJuIHsgQWRkckV4dGVybiB9IH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLi4ub24gTWVzc2FnZUhlYWRlckV4dEluTXNnSW5mb1ZhcmlhbnQge1xuICAgICAgICAgIEV4dEluTXNnSW5mbyB7XG4gICAgICAgICAgICBzcmMge1xuICAgICAgICAgICAgICAuLi5vbiBNc2dBZGRyZXNzRXh0QWRkckV4dGVyblZhcmlhbnQgeyBBZGRyRXh0ZXJuIHsgQWRkckV4dGVybiB9IH1cbiAgICAgICAgICAgICAgLi4ub24gTXNnQWRkcmVzc0V4dEFkZHJOb25lVmFyaWFudCB7IEFkZHJOb25lIHsgTm9uZSB9IH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLi4ub24gTWVzc2FnZUhlYWRlckludE1zZ0luZm9WYXJpYW50IHtcbiAgICAgICAgICBJbnRNc2dJbmZvIHtcbiAgICAgICAgICAgIHZhbHVlIHsgR3JhbXMgfVxuICAgICAgICAgICAgc3JjIHtcbiAgICAgICAgICAgICAgLi4ub24gTXNnQWRkcmVzc0ludEFkZHJWYXJWYXJpYW50IHsgQWRkclZhciB7IGFkZHJlc3MgfSB9XG4gICAgICAgICAgICAgIC4uLm9uIE1zZ0FkZHJlc3NJbnRBZGRyU3RkVmFyaWFudCB7IEFkZHJTdGQgeyBhZGRyZXNzIH0gfVxuICAgICAgICAgICAgICAuLi5vbiBNc2dBZGRyZXNzSW50QWRkck5vbmVWYXJpYW50IHsgQWRkck5vbmUgeyBOb25lIH0gfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbmA7XG5cbmFzeW5jIGZ1bmN0aW9uIHNweShkZXY6IERldiwgbmFtZXM6IHN0cmluZ1tdKSB7XG4gICAgY29uc29sZS5sb2codGV4dHMudXNhZ2VIZWFkZXIodmVyc2lvbikpO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKGRldi5uZXR3b3Jrcy5tYXAoYXN5bmMgKG5ldDogTmV0d29yaykgPT4ge1xuICAgICAgICBjb25zdCBuZXRBZGRyZXNzID0gYGh0dHA6Ly8wLjAuMC4wOiR7bmV0Lmhvc3RQb3J0IHx8ICc4MCd9YDtcbiAgICAgICAgY29uc29sZS5sb2coYFNweSBmb3IgJHtuZXQubmFtZX0gYXQgJHtuZXRBZGRyZXNzfWApO1xuICAgICAgICBjb25zdCBsb2NhbE5ldCA9IGF3YWl0IGNyZWF0ZUNsaWVudChuZXRBZGRyZXNzKTtcbiAgICAgICAgY29uc3QgYWNjb3VudHMgPSBhd2FpdCBsb2NhbE5ldC5xdWVyaWVzLmFjY291bnRzLnF1ZXJ5KHt9LCAnaWQnLCBbeyBwYXRoOiAnaWQnLCBkaXJlY3Rpb246ICdBU0MnIH1dLCAxMSk7XG4gICAgICAgIGNvbnNvbGUubG9nKCdBY2NvdW50czonKTtcbiAgICAgICAgYWNjb3VudHMuc2xpY2UoMCwgMTApLmZvckVhY2goeCA9PiBjb25zb2xlLmxvZyhgICAke3guaWR9YCkpO1xuICAgICAgICBpZiAoYWNjb3VudHMubGVuZ3RoID4gMTApIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCcgIGFuZCBtb3JlLi4uJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICBjb25zb2xlLmxvZygnTG9va2luZyBmb3IgdHJhbnNhY3Rpb25zIGFuZCBtb3JlLi4uIFByZXNzIFtFbnRlcl0gdG8gc3RvcC4uLicpO1xuICAgICAgICBsb2NhbE5ldC5xdWVyaWVzLnRyYW5zYWN0aW9ucy5zdWJzY3JpYmUoe30sIHRyYW5zYWN0aW9uUHJvamVjdGlvbiwgKGUsIHRyKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnVFJYOicsIHRyLmlkKTtcbiAgICAgICAgICAgIGNvbnN0IG1zZyA9IHRyLmluX21lc3NhZ2U7XG4gICAgICAgICAgICBjb25zdCBpbnRNc2cgPSBtc2cuaGVhZGVyLkludE1zZ0luZm87XG4gICAgICAgICAgICBpZiAoaW50TXNnKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJyAgICAnLCBgJHt0ci5hY2NvdW50X2FkZHJ9IDwtICR7aW50TXNnLnZhbHVlLkdyYW1zfSA8LSAke2ludE1zZy5zcmMuQWRkclN0ZC5hZGRyZXNzfWApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnICAgICcsIGAke3RyLmFjY291bnRfYWRkcn0gPC0gRVhUYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBsb2NhbE5ldC5xdWVyaWVzLmFjY291bnRzLnN1YnNjcmliZSh7fSwgJ2lkJywgKGUsIGQpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdBQ0M6JywgZC5pZCk7XG4gICAgICAgIH0pO1xuICAgIH0pKTtcblxuICAgIGF3YWl0IGlucHV0TGluZSgpO1xufVxuXG5cbmV4cG9ydCB7IHNweSB9O1xuIl19 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/utils/docker.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | // @flow 16 | import Docker from 'dockerode'; 17 | 18 | import {progress, progressDone, progressLine, versionToNumber} from "./utils"; 19 | 20 | export type DImageInfo = { 21 | Id: string, 22 | RepoTags: string[], 23 | RepoDigests: string[], 24 | } 25 | 26 | export type DMount = { 27 | Destination: string, 28 | Source: string, 29 | Type: 'bind' | 'volume' | 'tmpfs', 30 | } 31 | 32 | export type DContainerInfo = { 33 | Id: string, 34 | Names: string[], 35 | Image: string, 36 | ImageID: string, 37 | State: string, 38 | Mounts: DMount[], 39 | } 40 | 41 | export type DContainerExecOptions = { 42 | AttachStdin?: boolean, 43 | AttachStdout?: boolean, 44 | AttachStderr?: boolean, 45 | DetachKeys?: string, 46 | Tty?: boolean, 47 | Env?: string, 48 | Cmd?: string[], 49 | Privileged?: boolean, 50 | User?: string, 51 | WorkingDir?: string, 52 | } 53 | 54 | export type DockerModem = { 55 | followProgress( 56 | stream: any, 57 | onFinished: (err: any, output: any) => void, 58 | onProgress: (event: any) => void, 59 | ): void, 60 | 61 | demuxStream( 62 | stream: any, 63 | stdout: any, 64 | stderr: any, 65 | ): void, 66 | } 67 | 68 | export type DockerContainer = { 69 | id: string, 70 | modem: DockerModem, 71 | start(): Promise, 72 | exec(options: DContainerExecOptions, callback: any): void, 73 | stop(): Promise, 74 | remove(): Promise, 75 | } 76 | 77 | export type DockerImage = { 78 | remove(): Promise, 79 | } 80 | 81 | export type DPortBindings = { 82 | [string]: { HostIp: string, HostPort: string }[] 83 | }; 84 | 85 | export type DCreateContainerOptions = { 86 | name?: string, 87 | Image: string, 88 | Interactive?: boolean, 89 | Tty?: boolean, 90 | User?: string, 91 | Entrypoint?: string[], 92 | Env: string[], 93 | HostConfig?: { 94 | Mounts?: DMount[], 95 | }, 96 | ExposedPorts?: { 97 | [string]: {}, 98 | }, 99 | HostConfig?: { 100 | PortBindings?: DPortBindings, 101 | } 102 | } 103 | 104 | export type DVersion = { 105 | Version: string, 106 | } 107 | 108 | export type DockerClient = { 109 | version(): Promise, 110 | 111 | listContainers(options?: { all?: true }): Promise, 112 | 113 | listImages(options?: { all?: true }): Promise, 114 | 115 | getContainer(id: string): DockerContainer, 116 | 117 | getImage(name: string): DockerImage, 118 | 119 | createContainer(options: DCreateContainerOptions): Promise, 120 | 121 | pull(repoTag: string, auth: any, (err: any, stream: any) => void): void, 122 | 123 | modem: DockerModem, 124 | } 125 | 126 | export const ContainerStatus = { 127 | missing: 0, 128 | created: 1, 129 | running: 2, 130 | }; 131 | 132 | export type ContainerStatusType = 0 | 1 | 2; 133 | 134 | export interface ContainerDef { 135 | requiredImage: string, 136 | containerName: string, 137 | 138 | createContainer(docker: DevDocker): Promise 139 | } 140 | 141 | 142 | class DevDocker { 143 | client: DockerClient; 144 | _images: ?(DImageInfo[]); 145 | _containers: ?(DContainerInfo[]); 146 | _onStartupImagesPassed: boolean; 147 | onStartupImages: ?((images: DImageInfo[]) => void); 148 | onBeforePull: ?((repoTag: string) => Promise); 149 | 150 | constructor() { 151 | this.client = new Docker(); 152 | this.onStartupImages = null; 153 | this.onBeforePull = null; 154 | this._onStartupImagesPassed = false; 155 | this._images = null; 156 | this._containers = null; 157 | } 158 | 159 | dropCache() { 160 | this._images = null; 161 | this._containers = null; 162 | } 163 | 164 | async getImageInfos(): Promise { 165 | if (!this._images) { 166 | const images = await this.client.listImages({all: true}); 167 | this._images = images; 168 | if (!this._onStartupImagesPassed) { 169 | this._onStartupImagesPassed = true; 170 | if (this.onStartupImages) { 171 | this.onStartupImages(images); 172 | } 173 | } 174 | this._images = images; 175 | } 176 | return this._images || []; 177 | } 178 | 179 | async getContainerInfos(): Promise { 180 | if (!this._containers) { 181 | this._containers = await this.client.listContainers({all: true}); 182 | } 183 | return this._containers || []; 184 | } 185 | 186 | async numericVersion(): Promise { 187 | const version: DVersion = await this.client.version(); 188 | return versionToNumber(version.Version); 189 | } 190 | 191 | async removeImages(nameMatches: string[], containersOnly: boolean): Promise { 192 | // Stop and remove containers that belongs to images 193 | const containerInfos = (await this.getContainerInfos()).filter((info) => { 194 | return nameMatches.find(match => DevDocker.containersImageMatched(info, match)); 195 | }); 196 | for (let i = 0; i < containerInfos.length; i += 1) { 197 | const info = containerInfos[i]; 198 | progress(`Removing container [${DevDocker.containerTitle(info)}]`); 199 | const container = this.client.getContainer(info.Id); 200 | if (DevDocker.isRunning(info)) { 201 | await container.stop(); 202 | } 203 | await container.remove(); 204 | progressDone(); 205 | } 206 | if(containersOnly) { 207 | return; 208 | } 209 | // Remove images 210 | const imageInfos = (await this.getImageInfos()).filter((info) => { 211 | return nameMatches.find(match => DevDocker.imageHasMatchedName(info, match)); 212 | }); 213 | for (let i = 0; i < imageInfos.length; i += 1) { 214 | const info = imageInfos[i]; 215 | progress(`Removing image [${DevDocker.imageTitle(info)}]`); 216 | const image = this.client.getImage(info.Id); 217 | await image.remove(); 218 | progressDone(); 219 | } 220 | } 221 | 222 | async pull(repoTag: string): Promise { 223 | if (this.onBeforePull) { 224 | await this.onBeforePull(repoTag); 225 | } 226 | const client = this.client; 227 | const title = `Pulling [${repoTag}]`; 228 | progress(title); 229 | const image = await new Promise((resolve, reject) => { 230 | client.pull(repoTag, {}, function (err, stream) { 231 | if (!stream) { 232 | reject(err); 233 | return; 234 | } 235 | let lastReportTime = Date.now(); 236 | client.modem.followProgress(stream, onFinished, onProgress); 237 | 238 | function onFinished(err, output) { 239 | resolve(output); 240 | } 241 | 242 | function onProgress(event) { 243 | progressLine(`${title}... ${event.progress || ''}`); 244 | } 245 | }); 246 | }); 247 | progress(title); 248 | progressDone(); 249 | return image; 250 | } 251 | 252 | async findImageInfo(name: string): Promise { 253 | return (await this.getImageInfos()).find(x => DevDocker.imageHasMatchedName(x, name)) || null; 254 | } 255 | 256 | async findContainerInfo(name: string): Promise { 257 | return (await this.getContainerInfos()).find(x => DevDocker.hasName(x, name)) || null; 258 | } 259 | 260 | async shutdownContainer(def: ContainerDef, downTo: ContainerStatusType) { 261 | const info = await this.findContainerInfo(def.containerName); 262 | if (!info) { 263 | return; 264 | } 265 | if (downTo < ContainerStatus.running && DevDocker.isRunning(info)) { 266 | progress(`Stopping [${def.containerName}]`); 267 | await this.client.getContainer(info.Id).stop(); 268 | progressDone(); 269 | this.dropCache(); 270 | } 271 | if (downTo < ContainerStatus.created) { 272 | progress(`Removing [${def.containerName}]`); 273 | await this.client.getContainer(info.Id).remove(); 274 | progressDone(); 275 | this.dropCache(); 276 | } 277 | } 278 | 279 | async ensureImage(requiredImage: string) { 280 | if (!(await this.findImageInfo(requiredImage))) { 281 | await this.pull(requiredImage); 282 | this.dropCache(); 283 | } 284 | } 285 | 286 | async startupContainer(def: ContainerDef, upTo: ContainerStatusType) { 287 | await this.ensureImage(def.requiredImage); 288 | let info: ?DContainerInfo = await this.findContainerInfo(def.containerName); 289 | if (upTo >= ContainerStatus.created && !info) { 290 | progress(`Creating ${def.containerName}`); 291 | await def.createContainer(this); 292 | progressDone(); 293 | this.dropCache(); 294 | info = await this.findContainerInfo(def.containerName); 295 | } 296 | if (upTo >= ContainerStatus.running && info && !DevDocker.isRunning(info)) { 297 | progress(`Starting ${def.containerName}`); 298 | await this.client.getContainer(info.Id).start(); 299 | progressDone(); 300 | this.dropCache(); 301 | } 302 | } 303 | 304 | async shutdownContainers(defs: $ReadOnlyArray, downTo: ContainerStatusType) { 305 | for (let i = 0; i < defs.length; i += 1) { 306 | await this.shutdownContainer(defs[i], downTo); 307 | } 308 | } 309 | 310 | async startupContainers(defs: $ReadOnlyArray, upTo: ContainerStatusType) { 311 | for (let i = 0; i < defs.length; i += 1) { 312 | await this.startupContainer(defs[i], upTo); 313 | } 314 | } 315 | 316 | async ensureRunning(def: ContainerDef): Promise { 317 | await this.startupContainer(def, ContainerStatus.running); 318 | const info = await this.findContainerInfo(def.containerName); 319 | return this.client.getContainer((info && info.Id) || def.containerName); 320 | } 321 | 322 | static hasName(container: DContainerInfo, name: string): boolean { 323 | const nameToFind = `/${name}`.toLowerCase(); 324 | return !!(container.Names || []).find(n => n.toLowerCase() === nameToFind); 325 | } 326 | 327 | static imageTitle(info: DImageInfo): string { 328 | return DevDocker.imageNames(info)[0] || info.Id; 329 | } 330 | 331 | static containerTitle(info: DContainerInfo): string { 332 | return info.Names.map(name => name.startsWith('/') ? name.substr(1) : name).join(';'); 333 | } 334 | 335 | // if match specified with tag compare exactly 336 | // if match specified without tag compare untagged names 337 | static imageNameMatched(imageName: string, match: string): boolean { 338 | imageName = imageName.toLowerCase(); 339 | match = match.toLowerCase(); 340 | const matchParts = match.split(':'); 341 | if (matchParts.length > 1) { 342 | return imageName === match; 343 | } 344 | const imageParts = imageName.split(':'); 345 | return imageParts[0] === matchParts[0]; 346 | } 347 | 348 | static imageNames(info: DImageInfo): string[] { 349 | return [ 350 | ...(info.RepoTags || []), 351 | ...(info.RepoDigests || []).map((digest) => { 352 | return digest.split('@').join(':'); 353 | }), 354 | ]; 355 | } 356 | 357 | static imageHasMatchedName(info: DImageInfo, match: string): boolean { 358 | return !!DevDocker.imageNames(info).find(name => this.imageNameMatched(name, match)); 359 | } 360 | 361 | static isRunning(info: ?DContainerInfo): boolean { 362 | return !!info && info.State.toLowerCase() === 'running'; 363 | } 364 | 365 | static containersImageMatched(info: DContainerInfo, match: string): boolean { 366 | return this.imageNameMatched(info.Image, match); 367 | } 368 | } 369 | 370 | 371 | export { 372 | DevDocker, 373 | } 374 | -------------------------------------------------------------------------------- /src/cli/cli.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 TON DEV SOLUTIONS LTD. 3 | * 4 | * Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use 5 | * this file except in compliance with the License. You may obtain a copy of the 6 | * License at: https://www.ton.dev/licenses 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific TON DEV software governing permissions and 12 | * limitations under the License. 13 | * 14 | */ 15 | // @flow 16 | 17 | import { TONClient } from "ton-client-node-js"; 18 | import { ClientCode, ClientCodeLevel, JSModule } from "../compilers/client-code"; 19 | import { Solidity } from "../compilers/solidity"; 20 | import { Dev } from "../dev"; 21 | import { Network } from "../networks/networks"; 22 | import type { NetworkConfig } from "../networks/networks"; 23 | import { web } from "../server/server"; 24 | import { compilersWithNetworks } from "./options"; 25 | import type { 26 | CleanOptions, 27 | RecreateOptions, 28 | RestartOptions, SetNetworkOptions, 29 | SetupOptions, SolOptions, 30 | StartOptions, 31 | StopOptions, 32 | UseOptions, WebOptions, 33 | } from "./options"; 34 | 35 | import { infoCommand } from "./info.js"; 36 | import { spy } from "./spy"; 37 | import { Command } from 'commander'; 38 | 39 | const USE_EXPERIMENTAL_FEATURES = false; 40 | 41 | async function setupCommand(dev: Dev, options: SetupOptions) { 42 | await dev.start(compilersWithNetworks(dev, options)); 43 | } 44 | 45 | 46 | async function startCommand(dev: Dev, options: StartOptions) { 47 | await dev.start(compilersWithNetworks(dev, options)); 48 | } 49 | 50 | async function stopCommand(dev: Dev, options: StopOptions) { 51 | await dev.stop(compilersWithNetworks(dev, options)); 52 | } 53 | 54 | async function restartCommand(dev: Dev, options: RestartOptions) { 55 | await dev.restart(compilersWithNetworks(dev, options)); 56 | } 57 | 58 | async function recreateCommand(dev: Dev, options: RecreateOptions) { 59 | await dev.recreate(compilersWithNetworks(dev, options)); 60 | } 61 | 62 | async function cleanCommand(dev: Dev, options: CleanOptions) { 63 | const all = !options.compilers && !options.networks; 64 | await dev.clean( 65 | options.compilers || all, 66 | options.networks || all, 67 | options.containers, 68 | ); 69 | } 70 | 71 | async function setCommand(dev: Dev, names: string[], options: SetNetworkOptions) { 72 | await dev.updateNetworkConfigs(dev.networksOrAll(names), (config: NetworkConfig) => { 73 | if (options.newName) { 74 | config.name = options.newName; 75 | } 76 | if (options.port) { 77 | config.hostPort = options.port; 78 | } 79 | if (options.dbPort) { 80 | if (options.dbPort === 'bind') { 81 | config.arangoHostPort = Network.defaultArangoPort; 82 | } else if (options.dbPort === 'unbind') { 83 | config.arangoHostPort = ''; 84 | } else { 85 | config.arangoHostPort = options.dbPort || ''; 86 | } 87 | } 88 | }); 89 | } 90 | 91 | async function addCommand(dev: Dev, names: string[]) { 92 | await dev.addNetworks(names); 93 | } 94 | 95 | async function removeCommand(dev: Dev, names: string[]) { 96 | await dev.removeNetworks(dev.networksFromNames(names)); 97 | } 98 | 99 | async function generateKeysCommand(_dev: Dev) { 100 | const client = await TONClient.create({ 101 | servers: ['http://localhost'], 102 | }); 103 | const keys = await client.crypto.ed25519Keypair(); 104 | console.log(JSON.stringify(keys, undefined, 4)); 105 | } 106 | 107 | async function convertAddress(_dev: Dev, addr) { 108 | const client = await TONClient.create({ 109 | servers: ['http://localhost'], 110 | }); 111 | const showConverted = (title, converted) => { 112 | console.log(`${converted.address === addr ? '✓' : ' '} ${title} = ${converted.address}`); 113 | }; 114 | const showHex = async () => { 115 | const converted = await client.contracts.convertAddress({ 116 | address: addr, 117 | convertTo: 'Hex', 118 | }); 119 | showConverted('hex', converted); 120 | }; 121 | const showBase64 = async (test, bounce, url) => { 122 | const converted = await client.contracts.convertAddress({ 123 | address: addr, 124 | convertTo: 'Base64', 125 | base64Params: { 126 | bounce, 127 | test, 128 | url, 129 | }, 130 | }); 131 | const flags = [ 132 | test ? 'test' : 'main', 133 | bounce ? 'bounce' : '', 134 | url ? 'url' : '', 135 | ] 136 | .filter(x => x !== '') 137 | .join(' '); 138 | showConverted(flags, converted); 139 | }; 140 | await showHex(); 141 | await showBase64(false, false, false); 142 | await showBase64(false, false, true); 143 | await showBase64(false, true, false); 144 | await showBase64(false, true, true); 145 | await showBase64(true, false, false); 146 | await showBase64(true, false, true); 147 | await showBase64(true, true, false); 148 | await showBase64(true, true, true); 149 | } 150 | 151 | async function useCommand(dev: Dev, version: string, options: UseOptions) { 152 | await dev.useVersion(version, compilersWithNetworks(dev, options)); 153 | } 154 | 155 | async function solCommand(dev: Dev, files: string[], options: SolOptions) { 156 | if (files.length < 1) { 157 | throw new Error('You must specify at least one file name'); 158 | } 159 | await Solidity.build(dev, files, { 160 | clientLanguages: (options.clientLanguages || '').split(',').filter(x => x), 161 | clientLevel: options.clientLevel || ClientCodeLevel.run, 162 | jsModule: options.jsModule || JSModule.node, 163 | }); 164 | } 165 | 166 | async function genCommand(dev: Dev, files: string[], options: SolOptions) { 167 | if (files.length < 1) { 168 | throw new Error('You must specify at least one file name'); 169 | } 170 | await ClientCode.generate(files, { 171 | clientLanguages: (options.clientLanguages || '').split(','), 172 | clientLevel: options.clientLevel || ClientCodeLevel.run, 173 | jsModule: options.jsModule || JSModule.node, 174 | }); 175 | } 176 | 177 | async function spyCommand(dev: Dev, networks: string[]) { 178 | await spy(dev, networks); 179 | } 180 | 181 | async function webConsoleCommand(dev: Dev, options: WebOptions) { 182 | await web(dev, options); 183 | } 184 | 185 | const networksOption = [ 186 | '-n, --networks [names]', 187 | 'Apply command to specified network[s] (names must be separated with comma).' 188 | ]; 189 | 190 | const compilersOption = [ 191 | '-m, --compilers', 192 | 'Apply command to the compilers container.' 193 | ]; 194 | 195 | function getSupportedLanguages(): string[] { 196 | return Object.values(ClientCode.languages).map((x: any) => x.shortName); 197 | } 198 | 199 | const clientLanguagesOption = [ 200 | '-l, --client-languages ', 201 | `Generate client code for specified languages separated by comma, ` + 202 | `supported languages: "${getSupportedLanguages().join('", "')}".`, 203 | ]; 204 | 205 | const clientLevelOption = [ 206 | '-L, --client-level ', 207 | 'Client code level: ' + 208 | '"run" to run only, ' + 209 | '"deploy" to run and deploy (includes an imageBase64 of binary contract)', 210 | 'deploy' 211 | ]; 212 | 213 | const jsModuleTypeOption = [ 214 | '--js-module ', 215 | "Java Script module type: " + 216 | "`node` to use with `const FooContract = require('foo')`, " + 217 | "`nodeNoDefault` to use with `const {FooContract} = require('foo')`, " + 218 | "`es` to use with `import FooContract from 'foo'`, " + 219 | "`esNoDefault` to use with `import {FooContract} from 'foo'`.", 220 | 'node' 221 | ]; 222 | 223 | 224 | async function handleCommandLine(dev: Dev, args: string[]) { 225 | const program = new Command(); 226 | 227 | let commandAction = infoCommand; 228 | let commandArgs = []; 229 | 230 | const command = (action) => { 231 | return (...args) => { 232 | commandAction = action; 233 | commandArgs = args; 234 | }; 235 | }; 236 | 237 | program 238 | .name(dev.name) 239 | .version(dev.version) 240 | .option('-a, --available', 'Show available versions.') 241 | .description('TON Labs development tools'); 242 | 243 | program 244 | .command('info', { isDefault: true }).description('Show summary about dev environment.') 245 | .option('-a, --available', 'Show available versions.') 246 | .action(command(infoCommand)); 247 | 248 | program 249 | .command('sol [files...]').description('Build solidity contract[s].') 250 | .option(...clientLanguagesOption) 251 | .option(...clientLevelOption) 252 | .option(...jsModuleTypeOption) 253 | .action(command(solCommand)); 254 | 255 | program 256 | .command('gen [files...]').description('Generate client code for contract[s].') 257 | .option(clientLanguagesOption[0], clientLanguagesOption[1], 'js') 258 | .option(...clientLevelOption) 259 | .option(...jsModuleTypeOption) 260 | .action(command(genCommand)); 261 | 262 | program 263 | .command('start').description('Start dev containers.') 264 | .option(...networksOption) 265 | .option(...compilersOption) 266 | .action(command(startCommand)); 267 | 268 | program 269 | .command('stop').description('Stop dev containers.') 270 | .option(...networksOption) 271 | .option(...compilersOption) 272 | .action(command(stopCommand)); 273 | 274 | program 275 | .command('restart').description('Restart dev containers.') 276 | .option(...networksOption) 277 | .option(...compilersOption) 278 | .action(command(restartCommand)); 279 | 280 | program 281 | .command('recreate').description('Recreate dev containers.') 282 | .option(...networksOption) 283 | .option(...compilersOption) 284 | .action(command(recreateCommand)); 285 | 286 | program 287 | .command('setup').description('Setup dev environment.') 288 | .option(...networksOption) 289 | .option(...compilersOption) 290 | .action(command(setupCommand)); 291 | 292 | program 293 | .command('clean').description('Remove docker containers and images related to TON Dev.') 294 | .option('-n, --networks', 'Clean local node docker containers and images.') 295 | .option('-m, --compilers', 'Clean compilers docker containers and images.') 296 | .option('-c, --containers', 'Clean containers only.', false) 297 | .action(command(cleanCommand)); 298 | 299 | program 300 | .command('use ').description('Use specified version for containers.') 301 | .option(...networksOption) 302 | .option(...compilersOption) 303 | .action(command(useCommand)); 304 | 305 | program 306 | .command('set [network...]').description('Set network[s] options.') 307 | .option('-p, --port ', 'Host port to bound local node.') 308 | .option( 309 | '-d, --db-port ', 310 | 'Host port to bound local nodes Arango DB ("bind" to use default Arango DB port, "unbind" to unbind Arango DB port).', 311 | ) 312 | .option('-n, --new-name ', 'Set new name for network.') 313 | .action(command(setCommand)); 314 | 315 | program 316 | .command('add [network...]').description('Add network[s].') 317 | .action(command(addCommand)); 318 | 319 | program 320 | .command('remove [network...]').alias('rm').description('Remove network[s].') 321 | .action(command(removeCommand)); 322 | 323 | program 324 | .command('keys').alias('k').description('Generate random Key Pair.') 325 | .action(command(generateKeysCommand)); 326 | 327 | program 328 | .command('addr ').alias('a').description('Convert address.') 329 | .action(command(convertAddress)) 330 | .allowUnknownOption(true); 331 | 332 | if (USE_EXPERIMENTAL_FEATURES) { 333 | program 334 | .command('spy [networks...]').description('Run network scanner.') 335 | .action(command(spyCommand)); 336 | 337 | program 338 | .command('web').description('Run web console.') 339 | .option('-p, --port ', 'Host port to bound web console.', '8800') 340 | .action(command(webConsoleCommand)); 341 | 342 | 343 | } 344 | 345 | program.parse(args); 346 | 347 | if (commandArgs.length === 0) { 348 | if (program.args.length === 0) { 349 | await infoCommand(dev, program); 350 | } else { 351 | program.outputHelp(); 352 | } 353 | } else { 354 | if (commandAction === infoCommand) { 355 | const options = commandArgs[commandArgs.length - 1]; 356 | options.available = options.parent.available; 357 | } 358 | await commandAction(dev, ...commandArgs); 359 | } 360 | } 361 | 362 | export { handleCommandLine }; 363 | --------------------------------------------------------------------------------