From 43798a3eef3abe7588d3ef217ea2672ee5df8e99 Mon Sep 17 00:00:00 2001 From: shuse2 Date: Thu, 8 Feb 2018 22:24:35 +0100 Subject: [PATCH] Added flow sample --- .babelrc | 2 +- .eslintrc.json | 7 ++++- .flowconfig | 10 ++++++++ flow/types.js | 41 ++++++++++++++++++++++++++++++ package.json | 5 ++++ src/api/liskApi.js | 59 +++++++++++++++++++++++++++++++++++-------- src/api/privateApi.js | 46 ++++++++++++++++++++------------- src/api/utils.js | 38 +++++++++++++++++++--------- 8 files changed, 166 insertions(+), 42 deletions(-) create mode 100644 .flowconfig create mode 100644 flow/types.js diff --git a/.babelrc b/.babelrc index ff4523e61..92fa311f5 100644 --- a/.babelrc +++ b/.babelrc @@ -1,5 +1,5 @@ { - "presets": ["env"], + "presets": ["env", "flow"], "plugins": ["transform-runtime"], "env": { "test": { diff --git a/.eslintrc.json b/.eslintrc.json index 92791aacd..74f807f80 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -3,11 +3,16 @@ "globals": { "naclInstance": true }, + "parser": "babel-eslint", + "plugins": [ + "flowtype" + ], "rules": { "arrow-parens": ["error", "as-needed"], "curly": "off", "indent": "off", "no-confusing-arrow": "off", - "no-mixed-operators": "off" + "no-mixed-operators": "off", + "flowtype/define-flow-type": 2 } } diff --git a/.flowconfig b/.flowconfig new file mode 100644 index 000000000..fa69fe0b6 --- /dev/null +++ b/.flowconfig @@ -0,0 +1,10 @@ +[include] + +[ignore] +.*/node_modules/cypress/dist/* + +[libs] +flow/ + +[version] +^0.65.0 diff --git a/flow/types.js b/flow/types.js new file mode 100644 index 000000000..640b3db39 --- /dev/null +++ b/flow/types.js @@ -0,0 +1,41 @@ +/* + * Copyright © 2017 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + * @flow + */ + +declare type Options = { + ssl: boolean, + node: string, + randomPeer: boolean, + testnet: boolean, + port: string, + bannedPeers: Array, + nethash: NethashOption, +}; + +declare type NethashOption = { + 'Content-Type': string, + nethash: string, + broadhash: string, + os: string, + version: string, + minVersion: string, + port: string, + Accept: string, +}; + +declare type NethashOptions = { + mainnet: NethashOption, + testnet: NethashOption, +}; diff --git a/package.json b/package.json index d9e26f1c0..849083f0b 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "prettier": "prettier --write \"browsertest/{setup,runTests}.js\" \"{cypress/integration,src,test}/**/*.js\"", "serve:browsertest": "http-server browsertest", "jenkins": "grunt jenkins --verbose", + "flow": "flow", "build": "grunt build", "build:check": "node -e \"require('./dist-node')\"", "build:browsertest": "grunt build-browsertest", @@ -40,16 +41,20 @@ }, "devDependencies": { "babel-cli": "=6.24.1", + "babel-eslint": "=8.2.1", "babel-plugin-istanbul": "=4.1.4", "babel-plugin-rewire": "=1.1.0", "babel-plugin-transform-runtime": "=6.23.0", "babel-preset-env": "=1.6.0", + "babel-preset-flow": "=6.23.0", "chokidar-cli": "=1.2.0", "coveralls": "=2.13.1", "cypress": "=0.20.3", "eslint-config-airbnb-base": "=11.3.1", "eslint-config-lisk-base": "=0.1.0", + "eslint-plugin-flowtype": "=2.42.0", "eslint-plugin-import": "=2.7.0", + "flow-bin": "=0.65.0", "grunt": "=1.0.1", "grunt-browserify": "=5.0.0", "grunt-contrib-uglify": "=3.0.1", diff --git a/src/api/liskApi.js b/src/api/liskApi.js index 772714ca5..9bdd27a8f 100644 --- a/src/api/liskApi.js +++ b/src/api/liskApi.js @@ -11,6 +11,8 @@ * * Removal or modification of this copyright notice is prohibited. * + * @flow + * */ import config from '../../config.json'; import { LIVE_PORT, TEST_PORT, GET, POST } from '../constants'; @@ -18,7 +20,7 @@ import * as privateApi from './privateApi'; import * as utils from './utils'; export default class LiskAPI { - constructor(providedOptions) { + constructor(providedOptions: Options) { const options = Object.assign({}, config.options, providedOptions); this.defaultNodes = options.nodes || config.nodes.mainnet; @@ -40,7 +42,35 @@ export default class LiskAPI { this.nethash = this.getNethash(options.nethash); } - getNethash(providedNethash) { + defaultNodes: Array; + defaultSSLNodes: Array; + defaultTestnetNodes: Array; + options: Options; + ssl: boolean; + randomNode: boolean; + testnet: boolean; + bannedNodes: Array; + node: string; + port: string; + nethash: NethashOption; + + getAccount: Function; + getActiveDelegates: Function; + getStandbyDelegates: Function; + searchDelegatesByUsername: Function; + getBlocks: Function; + getForgedBlocks: Function; + getBlock: Function; + getTransactions: Function; + getTransaction: Function; + getVotes: Function; + getVoters: Function; + getUnsignedMultisignatureTransactions: Function; + getDapp: Function; + getDapps: Function; + getDappsByCategory: Function; + + getNethash(providedNethash: string): NethashOption { const { port } = this; const NetHash = this.testnet ? utils.netHashOptions({ port }).testnet @@ -65,12 +95,12 @@ export default class LiskAPI { }; } - setNode(node) { + setNode(node: string) { this.node = node || privateApi.selectNewNode.call(this); return this.node; } - setTestnet(testnet) { + setTestnet(testnet: boolean) { if (this.testnet !== testnet) { this.bannedNodes = []; } @@ -80,7 +110,7 @@ export default class LiskAPI { privateApi.selectNewNode.call(this); } - setSSL(ssl) { + setSSL(ssl: boolean) { if (this.ssl !== ssl) { this.ssl = ssl; this.bannedNodes = []; @@ -88,23 +118,27 @@ export default class LiskAPI { } } - broadcastTransactions(transactions) { + broadcastTransactions(transactions: Array) { return privateApi.sendRequestPromise .call(this, POST, 'transactions', transactions) .then(result => result.body); } - broadcastTransaction(transaction) { + broadcastTransaction(transaction: Object) { return this.broadcastTransactions([transaction]); } - broadcastSignatures(signatures) { + broadcastSignatures(signatures: Object) { return privateApi.sendRequestPromise .call(this, POST, 'signatures', { signatures }) .then(result => result.body); } - sendRequest(requestMethod, requestType, options) { + sendRequest( + requestMethod: string, + requestType: string, + options: Object | Array, + ) { const checkedOptions = utils.checkOptions(options); return privateApi.sendRequestPromise @@ -128,7 +162,12 @@ export default class LiskAPI { ); } - transferLSK(recipientId, amount, passphrase, secondPassphrase) { + transferLSK( + recipientId: string, + amount: number, + passphrase: string, + secondPassphrase: string, + ) { return this.sendRequest(POST, 'transactions', { recipientId, amount, diff --git a/src/api/privateApi.js b/src/api/privateApi.js index a4af7d815..2810f6520 100644 --- a/src/api/privateApi.js +++ b/src/api/privateApi.js @@ -11,22 +11,24 @@ * * Removal or modification of this copyright notice is prohibited. * + * @flow + * */ import * as popsicle from 'popsicle'; import { GET } from '../constants'; import * as utils from './utils'; -export function getNodes() { +export function getNodes(): Array { if (this.testnet) return this.defaultTestnetNodes; if (this.ssl) return this.defaultSSLNodes; return this.defaultNodes; } -export function isBanned(node) { +export function isBanned(node: string): boolean { return this.bannedNodes.includes(node); } -export function getRandomNode() { +export function getRandomNode(): string { const nodes = getNodes.call(this).filter(node => !isBanned.call(this, node)); if (!nodes.length) { @@ -39,7 +41,7 @@ export function getRandomNode() { return nodes[randomIndex]; } -export function selectNewNode() { +export function selectNewNode(): string { const providedNode = this.options.node; if (this.randomNode) { @@ -58,7 +60,7 @@ export function selectNewNode() { ); } -export function banActiveNode() { +export function banActiveNode(): boolean { if (!isBanned.call(this, this.node)) { this.bannedNodes.push(this.node); return true; @@ -66,7 +68,7 @@ export function banActiveNode() { return false; } -export function hasAvailableNodes() { +export function hasAvailableNodes(): boolean { const nodes = getNodes.call(this); return this.randomNode @@ -74,7 +76,11 @@ export function hasAvailableNodes() { : false; } -export function createRequestObject(method, requestType, providedOptions) { +export function createRequestObject( + method: string, + requestType: string, + providedOptions: Object | Array, +) { const options = providedOptions || {}; const baseURL = utils.getFullURL(this); const url = @@ -90,7 +96,11 @@ export function createRequestObject(method, requestType, providedOptions) { }; } -export function sendRequestPromise(requestMethod, requestType, options) { +export function sendRequestPromise( + requestMethod: string, + requestType: string, + options: Object | Array, +) { const requestObject = createRequestObject.call( this, requestMethod, @@ -104,11 +114,11 @@ export function sendRequestPromise(requestMethod, requestType, options) { } export function handleTimestampIsInFutureFailures( - requestMethod, - requestType, - options, - result, -) { + requestMethod: string, + requestType: string, + options: any, + result: Object, +): Promise<*> { if ( !result.success && result.message && @@ -125,11 +135,11 @@ export function handleTimestampIsInFutureFailures( } export function handleSendRequestFailures( - requestMethod, - requestType, - options, - error, -) { + requestMethod: string, + requestType: string, + options: Object | Array, + error: Error, +): Promise<*> { const that = this; if (hasAvailableNodes.call(that)) { return new Promise((resolve, reject) => { diff --git a/src/api/utils.js b/src/api/utils.js index a8b8b0ffd..9392fc85c 100644 --- a/src/api/utils.js +++ b/src/api/utils.js @@ -11,16 +11,17 @@ * * Removal or modification of this copyright notice is prohibited. * + * @flow */ import { LIVE_PORT, SSL_PORT, TEST_PORT } from '../constants'; -export const getDefaultPort = options => { +export const getDefaultPort = (options: Options): string => { if (options.testnet) return TEST_PORT; if (options.ssl) return SSL_PORT; return LIVE_PORT; }; -export const netHashOptions = ({ port }) => { +export const netHashOptions = ({ port }: Object): NethashOptions => { const testnetNethash = 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba'; const mainnetNethash = @@ -47,36 +48,49 @@ export const netHashOptions = ({ port }) => { }; }; -export const getURLPrefix = ({ ssl }) => (ssl ? 'https' : 'http'); +export const getURLPrefix = ({ ssl }: { ssl: boolean }): string => + ssl ? 'https' : 'http'; -export const getFullURL = ({ node, port, ssl }) => { +export const getFullURL = ({ + node, + port, + ssl, +}: { + node: string, + port: string, + ssl: boolean, +}): string => { const nodeUrl = port ? `${node}:${port}` : node; return `${getURLPrefix({ ssl })}://${nodeUrl}`; }; -export const wrapSendRequest = (method, endpoint, getDataFn) => - function wrappedSendRequest(value, options) { +export const wrapSendRequest = ( + method: string, + endpoint: string, + getDataFn: Function, +) => + function wrappedSendRequest(value: string, options: Object) { const providedOptions = options || {}; const providedData = getDataFn(value, providedOptions); const data = Object.assign({}, providedData, providedOptions); return this.sendRequest(method, endpoint, data); }; -export const checkOptions = (options = {}) => { - Object.entries(options).forEach(([key, value]) => { +export const checkOptions = (options: Object | Array = {}) => { + Object.entries(options).forEach(([key: string, value: number]) => { if (value === undefined || Number.isNaN(value)) { - throw new Error(`"${key}" option should not be ${value}`); + throw new Error(`"${key}" option should not be ${String(value)}`); } }); return options; }; -export const toQueryString = obj => { +export const toQueryString = (obj: Object | Array): string => { const parts = Object.entries(obj).reduce( - (accumulator, [key, value]) => [ + (accumulator, [key: string, value: mixed]) => [ ...accumulator, - `${encodeURIComponent(key)}=${encodeURIComponent(value)}`, + `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`, ], [], );