Add flow type checking

This commit is contained in:
Chris Clark
2015-06-04 18:51:03 -07:00
parent 7cbcb9a220
commit 76d8c8b061
12 changed files with 42 additions and 61 deletions

View File

@@ -1,7 +1,11 @@
[ignore] [ignore]
.*/src/.*
.*/dist/.*
.*/test/fixtures/.*
[include] [include]
[libs] [libs]
[options] [options]
module.system=node

View File

@@ -1,18 +1,17 @@
sudo: false # use faster docker containers
language: node_js language: node_js
node_js: node_js:
- "0.12" - "0.12"
before_script: before_script:
- npm install -g eslint - npm install -g eslint
- npm install -g esprima-fb # allow flow type annotations in eslint
- curl 'https://raw.githubusercontent.com/ripple/javascript-style-guide/es6/eslintrc' > ./eslintrc - curl 'https://raw.githubusercontent.com/ripple/javascript-style-guide/es6/eslintrc' > ./eslintrc
- 'echo "parser: esprima-fb" >> ./eslintrc'
- eslint --reset -c ./eslintrc $(git --no-pager diff --name-only -M100% --diff-filter=AM --relative $(git merge-base FETCH_HEAD origin/HEAD) FETCH_HEAD | grep "\.js$") - eslint --reset -c ./eslintrc $(git --no-pager diff --name-only -M100% --diff-filter=AM --relative $(git merge-base FETCH_HEAD origin/HEAD) FETCH_HEAD | grep "\.js$")
- npm install -g flow-bin
- npm run typecheck
script: MOCHA_REPORTER=tap npm test --coverage script: MOCHA_REPORTER=tap npm test --coverage
after_success: after_success:
- npm run coveralls - npm run coveralls
notifications: notifications:
email: false email: false
webhooks:
urls:
- https://webhooks.gitter.im/e/d1ec4245f90231619d30
on_success: change # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: false # default: false

View File

@@ -3,17 +3,10 @@
'use strict'; 'use strict';
var _ = require('lodash'); var _ = require('lodash');
var gulp = require('gulp'); var gulp = require('gulp');
var gutil = require('gulp-util');
var watch = require('gulp-watch');
var plumber = require('gulp-plumber');
var filelog = require('gulp-filelog');
var cleanDest = require('gulp-clean-dest');
var uglify = require('gulp-uglify'); var uglify = require('gulp-uglify');
var rename = require('gulp-rename'); var rename = require('gulp-rename');
var webpack = require('webpack'); var webpack = require('webpack');
var bump = require('gulp-bump'); var bump = require('gulp-bump');
var react = require('gulp-react');
var flow = require('gulp-flowtype');
var argv = require('yargs').argv; var argv = require('yargs').argv;
var pkg = require('./package.json'); var pkg = require('./package.json');
@@ -39,10 +32,6 @@ function webpackConfig(extension, overrides) {
return _.assign({}, defaults, overrides); return _.assign({}, defaults, overrides);
} }
function logPluginError(error) {
gutil.log(error.toString());
}
gulp.task('build', function(callback) { gulp.task('build', function(callback) {
webpack(webpackConfig('.js'), callback); webpack(webpackConfig('.js'), callback);
}); });
@@ -118,25 +107,6 @@ gulp.task('watch', function() {
gulp.watch('src/*', ['build-debug']); gulp.watch('src/*', ['build-debug']);
}); });
// To use this, each javascript file must have /* @flow */ on the first line
gulp.task('typecheck', function() {
return gulp.src('src/*.js')
.pipe(flow({ // note: do not set the 'all' option, it is broken
weak: true, // remove this after all errors are addressed
killFlow: true
}));
});
gulp.task('strip', function() {
return gulp.src('src/*.js')
.pipe(watch('src/*.js'))
.pipe(cleanDest('out')) // delete outdated output file before stripping
.pipe(plumber()) // prevent an error in one file from ending build
.pipe(react({stripTypes: true}).on('error', logPluginError))
.pipe(filelog())
.pipe(gulp.dest('out'));
});
gulp.task('version-bump', function() { gulp.task('version-bump', function() {
if (!argv.type) { if (!argv.type) {
throw new Error('No type found, pass it in using the --type argument'); throw new Error('No type found, pass it in using the --type argument');

View File

@@ -15,7 +15,7 @@
}, },
"dependencies": { "dependencies": {
"async": "~0.9.0", "async": "~0.9.0",
"babel-runtime": "^5.3.2", "babel-runtime": "^5.5.4",
"bignumber.js": "^2.0.3", "bignumber.js": "^2.0.3",
"extend": "~1.2.1", "extend": "~1.2.1",
"is-my-json-valid": "^2.12.0", "is-my-json-valid": "^2.12.0",
@@ -29,38 +29,31 @@
}, },
"devDependencies": { "devDependencies": {
"assert-diff": "^1.0.1", "assert-diff": "^1.0.1",
"babel": "~5.4.7", "babel": "^5.5.4",
"babel-core": "~5.4.7", "babel-core": "^5.5.4",
"babel-loader": "^5.0.0", "babel-loader": "^5.0.0",
"coveralls": "~2.10.0", "coveralls": "~2.10.0",
"eslint": "^0.18.0", "eslint": "^0.18.0",
"eventemitter2": "^0.4.14", "eventemitter2": "^0.4.14",
"gulp": "~3.8.10", "gulp": "~3.8.10",
"gulp-bump": "~0.1.13", "gulp-bump": "~0.1.13",
"gulp-clean-dest": "^0.1.0",
"gulp-filelog": "^0.4.1",
"gulp-flowtype": "^0.4.1",
"gulp-plumber": "^0.6.6",
"gulp-react": "^2.0.0",
"gulp-rename": "~1.2.0", "gulp-rename": "~1.2.0",
"gulp-uglify": "~1.1.0", "gulp-uglify": "~1.1.0",
"gulp-util": "^3.0.3",
"gulp-watch": "^4.1.0",
"istanbul": "~0.3.5", "istanbul": "~0.3.5",
"map-stream": "~0.1.0",
"mocha": "~2.1.0", "mocha": "~2.1.0",
"nock": "^0.34.1",
"webpack": "~1.5.3", "webpack": "~1.5.3",
"yargs": "~1.3.1" "yargs": "~1.3.1"
}, },
"scripts": { "scripts": {
"build": "gulp", "build": "gulp",
"clean": "rm -rf dist/npm && rm -rf build/flow",
"typecheck": "babel -i runtime --blacklist flow -d build/flow/ src/ && flow",
"compile": "babel -i runtime -d dist/npm/ src/", "compile": "babel -i runtime -d dist/npm/ src/",
"compile-with-source-maps": "babel -i runtime -s -t -d dist/npm/ src/", "compile-with-source-maps": "babel -i runtime -s -t -d dist/npm/ src/",
"prepublish": "npm run compile", "prepublish": "npm run clean && npm run compile",
"test": "istanbul test _mocha", "test": "istanbul test _mocha",
"coveralls": "cat ./coverage/lcov.info | coveralls", "coveralls": "cat ./coverage/lcov.info | coveralls",
"lint": "if ! [ -f eslintrc ]; then curl -o eslintrc 'https://raw.githubusercontent.com/ripple/javascript-style-guide/es6/eslintrc'; fi; eslint --reset -c eslintrc src/*.js", "lint": "if ! [ -f eslintrc ]; then curl -o eslintrc 'https://raw.githubusercontent.com/ripple/javascript-style-guide/es6/eslintrc'; echo 'parser: esprima-fb' >> eslintrc; fi; eslint --reset -c eslintrc src/",
"perf": "./scripts/perf_test.sh" "perf": "./scripts/perf_test.sh"
}, },
"repository": { "repository": {

View File

@@ -1,3 +1,4 @@
/* @flow */
'use strict'; 'use strict';
const _ = require('lodash'); const _ = require('lodash');
const utils = require('./utils'); const utils = require('./utils');
@@ -34,9 +35,9 @@ function createOrderTransaction(account, order) {
const _order = renameCounterpartyToIssuerInOrder(order); const _order = renameCounterpartyToIssuerInOrder(order);
const transaction = new ripple.Transaction(); const transaction = new ripple.Transaction();
const takerPays = _order.taker_pays.currency !== 'XRP' const takerPays = _order.taker_pays.currency !== 'XRP'
? _order.taker_pays : utils.xrpToDrops(_order.taker_pays.value); ? _order.taker_pays : utils.common.xrpToDrops(_order.taker_pays.value);
const takerGets = _order.taker_gets.currency !== 'XRP' const takerGets = _order.taker_gets.currency !== 'XRP'
? _order.taker_gets : utils.xrpToDrops(_order.taker_gets.value); ? _order.taker_gets : utils.common.xrpToDrops(_order.taker_gets.value);
transaction.offerCreate(account, ripple.Amount.from_json(takerPays), transaction.offerCreate(account, ripple.Amount.from_json(takerPays),
ripple.Amount.from_json(takerGets)); ripple.Amount.from_json(takerGets));

View File

@@ -1,3 +1,4 @@
/* @flow */
'use strict'; 'use strict';
const utils = require('./utils'); const utils = require('./utils');
const validate = utils.common.validate; const validate = utils.common.validate;

View File

@@ -1,3 +1,4 @@
/* @flow */
/* eslint-disable valid-jsdoc */ /* eslint-disable valid-jsdoc */
'use strict'; 'use strict';
const BigNumber = require('bignumber.js'); const BigNumber = require('bignumber.js');
@@ -77,7 +78,7 @@ function createPaymentTransaction(account, payment) {
.plus(payment.source.slippage || 0).toString(); .plus(payment.source.slippage || 0).toString();
if (payment.source_amount.currency === 'XRP') { if (payment.source_amount.currency === 'XRP') {
transaction.sendMax(utils.xrpToDrops(maxValue)); transaction.sendMax(utils.common.utils.xrpToDrops(maxValue));
} else { } else {
transaction.sendMax({ transaction.sendMax({
value: maxValue, value: maxValue,

View File

@@ -1,3 +1,4 @@
/* @flow */
/* eslint-disable valid-jsdoc */ /* eslint-disable valid-jsdoc */
'use strict'; 'use strict';
const _ = require('lodash'); const _ = require('lodash');

View File

@@ -1,3 +1,4 @@
/* @flow */
'use strict'; 'use strict';
const utils = require('./utils'); const utils = require('./utils');
const ripple = utils.common.core; const ripple = utils.common.core;
@@ -37,7 +38,7 @@ function hashJSON(txJSON, prefix) {
return hashSerialization(serialize(txJSON), prefix); return hashSerialization(serialize(txJSON), prefix);
} }
function signingHash(txJSON, isTestNet) { function signingHash(txJSON, isTestNet=false) {
return hashJSON(txJSON, isTestNet ? HASH_TX_SIGN_TESTNET : HASH_TX_SIGN); return hashJSON(txJSON, isTestNet ? HASH_TX_SIGN_TESTNET : HASH_TX_SIGN);
} }
@@ -46,11 +47,14 @@ function computeSignature(txJSON, keypair) {
return ripple.sjcl.codec.hex.fromBits(signature).toUpperCase(); return ripple.sjcl.codec.hex.fromBits(signature).toUpperCase();
} }
function sign(txJSON, secret) { /*:: type TxJSON = {Account: string; SigningPubKey: string,
TxnSignature: string};
type Signed = {tx_blob: string; hash: string}; */
function sign(txJSON: TxJSON, secret: string): Signed {
validate.txJSON(txJSON); validate.txJSON(txJSON);
validate.addressAndSecret({address: txJSON.Account, secret: secret}); validate.addressAndSecret({address: txJSON.Account, secret: secret});
const keypair = getKeyPair(txJSON.Acccount, secret); const keypair = getKeyPair(txJSON.Account, secret);
if (txJSON.SigningPubKey === undefined) { if (txJSON.SigningPubKey === undefined) {
txJSON.SigningPubKey = getPublicKeyHex(keypair); txJSON.SigningPubKey = getPublicKeyHex(keypair);
} }

View File

@@ -1,9 +1,11 @@
/* @flow */
'use strict'; 'use strict';
const utils = require('./utils'); const utils = require('./utils');
const ripple = utils.common.core; const ripple = utils.common.core;
const validate = utils.common.validate; const validate = utils.common.validate;
function submit(tx_blob, callback) { /*:: type Callback = (err: any, data: any) => void */
function submit(tx_blob: string, callback: Callback): void {
validate.blob(tx_blob); validate.blob(tx_blob);
const request = new ripple.Request(this.remote, 'submit'); const request = new ripple.Request(this.remote, 'submit');
request.message.tx_blob = tx_blob; request.message.tx_blob = tx_blob;

View File

@@ -1,3 +1,4 @@
/* @flow */
'use strict'; 'use strict';
const utils = require('./utils'); const utils = require('./utils');
const ripple = utils.common.core; const ripple = utils.common.core;

View File

@@ -1,3 +1,4 @@
/* @flow */
/* eslint-disable valid-jsdoc */ /* eslint-disable valid-jsdoc */
'use strict'; 'use strict';
const BigNumber = require('bignumber.js'); const BigNumber = require('bignumber.js');
@@ -18,7 +19,8 @@ const common = require('../common');
* *
* @returns undefined * @returns undefined
*/ */
function setTransactionBitFlags(transaction, options) { /*:: type FlagOptions = {flags: any; input: any; clear_setting?: string} */
function setTransactionBitFlags(transaction: any, options: FlagOptions): void {
for (let flagName in options.flags) { for (let flagName in options.flags) {
const flag = options.flags[flagName]; const flag = options.flags[flagName];
@@ -46,7 +48,9 @@ function getFeeDrops(remote) {
return remote.feeTx(feeUnits).to_text(); return remote.feeTx(feeUnits).to_text();
} }
function createTxJSON(transaction, remote, instructions, callback) { /*:: type Callback = (err: typeof Error, data: {tx_json: any}) => void */
function createTxJSON(transaction: any, remote: any,
instructions: any, callback: Callback): void {
common.validate.instructions(instructions); common.validate.instructions(instructions);
transaction.complete(); transaction.complete();
@@ -85,12 +89,12 @@ function createTxJSON(transaction, remote, instructions, callback) {
} }
} }
function wrapCatch(asyncFunction) { function wrapCatch(asyncFunction: any): any {
return function() { return function() {
const callback = arguments[arguments.length - 1];
try { try {
asyncFunction.apply(this, arguments); asyncFunction.apply(this, arguments);
} catch (error) { } catch (error) {
const callback = arguments[arguments.length - 1];
callback(error); callback(error);
} }
}; };