Skip to content
This repository has been archived by the owner on Apr 15, 2019. It is now read-only.

620 - Update util std functions #625

Merged
merged 4 commits into from
Oct 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/commands/signature/broadcast.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,25 @@
*/
import BaseCommand from '../../base';
import { ValidationError } from '../../utils/error';
import { getRawStdIn } from '../../utils/input/utils';
import { getStdIn } from '../../utils/input/utils';
import getAPIClient from '../../utils/api';

const getSignatureInput = async () => {
const rawStdIn = await getRawStdIn();
if (rawStdIn.length <= 0) {
try {
const { data } = await getStdIn({ dataIsRequired: true });
if (!data) {
throw new ValidationError('No signature was provided.');
}
return data;
} catch (e) {
throw new ValidationError('No signature was provided.');
}
return rawStdIn[0];
};

export default class BroadcastCommand extends BaseCommand {
async run() {
const { args: { signature } } = this.parse(BroadcastCommand);
const signatureInput = signature || (await getSignatureInput(signature));
const signatureInput = signature || (await getSignatureInput());
let signatureObject;
try {
signatureObject = JSON.parse(signatureInput);
Expand Down
25 changes: 12 additions & 13 deletions src/commands/signature/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,23 @@
import elements from 'lisk-elements';
import { flags as flagParser } from '@oclif/command';
import BaseCommand from '../../base';
import { getRawStdIn } from '../../utils/input/utils';
import { getStdIn } from '../../utils/input/utils';
import { ValidationError } from '../../utils/error';
import parseTransactionString from '../../utils/transactions';
import getInputsFromSources from '../../utils/input';
import commonFlags from '../../utils/flags';

const getTransactionInput = async () =>
getRawStdIn()
.then(rawStdIn => {
if (rawStdIn.length <= 0) {
throw new ValidationError('No transaction was provided.');
}
return rawStdIn[0];
})
.catch(() => {
const getTransactionInput = async () => {
try {
const { data } = await getStdIn({ dataIsRequired: true });
if (!data) {
throw new ValidationError('No transaction was provided.');
});
}
return data;
} catch (e) {
throw new ValidationError('No transaction was provided.');
}
};

export default class CreateCommand extends BaseCommand {
async run() {
Expand All @@ -41,8 +41,7 @@ export default class CreateCommand extends BaseCommand {
flags: { passphrase: passphraseSource },
} = this.parse(CreateCommand);

const transactionInput =
transaction || (await getTransactionInput(transaction));
const transactionInput = transaction || (await getTransactionInput());

const transactionObject = parseTransactionString(transactionInput);

Expand Down
25 changes: 12 additions & 13 deletions src/commands/transaction/broadcast.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,25 @@
import BaseCommand from '../../base';
import parseTransactionString from '../../utils/transactions';
import { ValidationError } from '../../utils/error';
import { getRawStdIn } from '../../utils/input/utils';
import { getStdIn } from '../../utils/input/utils';
import getAPIClient from '../../utils/api';

const getTransactionInput = async () =>
getRawStdIn()
.then(rawStdIn => {
if (rawStdIn.length <= 0) {
throw new ValidationError('No transaction was provided.');
}
return rawStdIn[0];
})
.catch(() => {
const getTransactionInput = async () => {
try {
const { data } = await getStdIn({ dataIsRequired: true });
if (!data) {
throw new ValidationError('No transaction was provided.');
});
}
return data;
} catch (e) {
throw new ValidationError('No transaction was provided.');
}
};

export default class BroadcastCommand extends BaseCommand {
async run() {
const { args: { transaction } } = this.parse(BroadcastCommand);
const transactionInput =
transaction || (await getTransactionInput(transaction));
const transactionInput = transaction || (await getTransactionInput());
const transactionObject = parseTransactionString(transactionInput);
const client = getAPIClient(this.userConfig.api);
const response = await client.transactions.broadcast(transactionObject);
Expand Down
26 changes: 12 additions & 14 deletions src/commands/transaction/sign.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,23 @@
import elements from 'lisk-elements';
import { flags as flagParser } from '@oclif/command';
import BaseCommand from '../../base';
import { getRawStdIn } from '../../utils/input/utils';
import { getStdIn } from '../../utils/input/utils';
import { ValidationError } from '../../utils/error';
import parseTransactionString from '../../utils/transactions';
import getInputsFromSources from '../../utils/input';
import commonFlags from '../../utils/flags';

const getTransactionInput = async () =>
getRawStdIn()
.then(rawStdIn => {
if (rawStdIn.length <= 0) {
throw new ValidationError('No transaction was provided.');
}
return rawStdIn[0];
})
.catch(() => {
const getTransactionInput = async () => {
try {
const { data } = await getStdIn({ dataIsRequired: true });
if (!data) {
throw new ValidationError('No transaction was provided.');
});
}
return data;
} catch (e) {
throw new ValidationError('No transaction was provided.');
}
};

export default class SignCommand extends BaseCommand {
async run() {
Expand All @@ -44,9 +44,7 @@ export default class SignCommand extends BaseCommand {
},
} = this.parse(SignCommand);

const transactionInput =
transaction || (await getTransactionInput(transaction));

const transactionInput = transaction || (await getTransactionInput());
const transactionObject = parseTransactionString(transactionInput);

const { passphrase, secondPassphrase } = await getInputsFromSources({
Expand Down
22 changes: 11 additions & 11 deletions src/commands/transaction/verify.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import elements from 'lisk-elements';
import { flags as flagParser } from '@oclif/command';
import BaseCommand from '../../base';
import parseTransactionString from '../../utils/transactions';
import { getRawStdIn, getData } from '../../utils/input/utils';
import { getStdIn, getData } from '../../utils/input/utils';
import { ValidationError } from '../../utils/error';

const secondPublicKeyDescription = `Specifies a source for providing a second public key to the command. The second public key must be provided via this option. Sources must be one of \`file\` or \`stdin\`. In the case of \`file\`, a corresponding identifier must also be provided.
Expand All @@ -29,17 +29,17 @@ const secondPublicKeyDescription = `Specifies a source for providing a second pu
- --second-public-key 790049f919979d5ea42cca7b7aa0812cbae8f0db3ee39c1fe3cef18e25b67951
`;

const getTransactionInput = async () =>
getRawStdIn()
.then(rawStdIn => {
if (rawStdIn.length <= 0) {
throw new ValidationError('No transaction was provided.');
}
return rawStdIn[0];
})
.catch(() => {
const getTransactionInput = async () => {
try {
const { data } = await getStdIn({ dataIsRequired: true });
if (!data) {
throw new ValidationError('No transaction was provided.');
});
}
return data;
} catch (e) {
throw new ValidationError('No transaction was provided.');
}
};

const processSecondPublicKey = async secondPublicKey =>
secondPublicKey.includes(':') ? getData(secondPublicKey) : secondPublicKey;
Expand Down
4 changes: 3 additions & 1 deletion src/utils/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,6 @@ export const handleEPIPE = err => {
}
};

export const isTTY = () => !process.stdout.isTTY;
export const stdoutIsTTY = () => process.stdout.isTTY;

export const stdinIsTTY = () => process.stdin.isTTY;
34 changes: 10 additions & 24 deletions src/utils/input/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import fs from 'fs';
import readline from 'readline';
import inquirer from 'inquirer';
import { FileSystemError, ValidationError } from '../error';
import { isTTY } from '../helpers';
import { stdinIsTTY, stdoutIsTTY } from '../helpers';

const capitalise = text => `${text.charAt(0).toUpperCase()}${text.slice(1)}`;

Expand All @@ -44,32 +44,13 @@ export const splitSource = source => {
};
};

const timeoutPromise = ms =>
new Promise((resolve, reject) => {
const id = setTimeout(() => {
clearTimeout(id);
reject(new Error(`Timed out after ${ms} ms`));
}, ms);
});

export const getRawStdIn = () => {
const readFromStd = new Promise(resolve => {
const rl = readline.createInterface({ input: process.stdin });
const lines = [];
return rl
.on('line', line => lines.push(line))
.on('close', () => resolve(lines));
});
return Promise.race([readFromStd, timeoutPromise(DEFAULT_TIMEOUT)]);
};

export const getStdIn = ({
passphraseIsRequired,
secondPassphraseIsRequired,
passwordIsRequired,
dataIsRequired,
} = {}) => {
const readFromStd = new Promise(resolve => {
const readFromStd = new Promise((resolve, reject) => {
if (
!(
passphraseIsRequired ||
Expand All @@ -80,10 +61,15 @@ export const getStdIn = ({
) {
return resolve({});
}

const lines = [];
const rl = readline.createInterface({ input: process.stdin });

// Prevent readline hanging when command called with no input or piped
const id = setTimeout(() => {
clearTimeout(id);
reject(new Error(`Timed out after ${DEFAULT_TIMEOUT} ms`));
}, DEFAULT_TIMEOUT);

const handleClose = () => {
const passphraseIndex = 0;
const passphrase = passphraseIsRequired ? lines[passphraseIndex] : null;
Expand All @@ -109,7 +95,7 @@ export const getStdIn = ({

return rl.on('line', line => lines.push(line)).on('close', handleClose);
});
return Promise.race([readFromStd, timeoutPromise(DEFAULT_TIMEOUT)]);
return readFromStd;
};

export const getPassphraseFromPrompt = async ({
Expand All @@ -132,7 +118,7 @@ export const getPassphraseFromPrompt = async ({
}

// Prompting user for additional input when piping commands causes error with stdin
if (isTTY()) {
if (!stdoutIsTTY() || !stdinIsTTY()) {
throw new Error(
`Please enter ${displayName} using a flag when piping data.`,
);
Expand Down
14 changes: 7 additions & 7 deletions test/commands/signature/broadcast.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ describe('signature:broadcast', () => {
.stub(api, 'default', sandbox.stub().returns(apiClientStub))
.stub(
inputUtils,
'getRawStdIn',
sandbox.stub().resolves(defaultSignatureString),
'getStdIn',
sandbox.stub().resolves({ data: defaultSignatureString }),
)
.stdout();

describe('signature:broadcast', () => {
setupTest()
.stub(inputUtils, 'getRawStdIn', sandbox.stub().resolves([]))
.stub(inputUtils, 'getStdIn', sandbox.stub().resolves({}))
.command(['signature:broadcast'])
.catch(error => {
return expect(error.message).to.contain('No signature was provided.');
Expand Down Expand Up @@ -84,8 +84,8 @@ describe('signature:broadcast', () => {
setupTest()
.stub(
inputUtils,
'getRawStdIn',
sandbox.stub().resolves(['{invalid: json, format: bad}']),
'getStdIn',
sandbox.stub().resolves({ data: '{invalid: json, format: bad}' }),
)
.command(['signature:broadcast'])
.catch(error => {
Expand All @@ -98,8 +98,8 @@ describe('signature:broadcast', () => {
setupTest()
.stub(
inputUtils,
'getRawStdIn',
sandbox.stub().resolves([defaultSignatureString]),
'getStdIn',
sandbox.stub().resolves({ data: defaultSignatureString }),
)
.command(['signature:broadcast'])
.it('should broadcast the signature', () => {
Expand Down
16 changes: 8 additions & 8 deletions test/commands/signature/create.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ describe('signature:create', () => {
setupTest()
.stub(
inputUtils,
'getRawStdIn',
'getStdIn',
sandbox.stub().rejects(new Error('Timeout error')),
)
.command(['signature:create'])
Expand Down Expand Up @@ -138,7 +138,7 @@ describe('signature:create', () => {

describe('transaction | signature:create', () => {
setupTest()
.stub(inputUtils, 'getRawStdIn', sandbox.stub().resolves([]))
.stub(inputUtils, 'getStdIn', sandbox.stub().resolves({}))
.command(['signature:create'])
.catch(error => {
return expect(error.message).to.contain('No transaction was provided.');
Expand All @@ -148,8 +148,8 @@ describe('signature:create', () => {
setupTest()
.stub(
inputUtils,
'getRawStdIn',
sandbox.stub().resolves([invalidTransaction]),
'getStdIn',
sandbox.stub().resolves({ data: invalidTransaction }),
)
.command(['signature:create'])
.catch(error => {
Expand All @@ -162,8 +162,8 @@ describe('signature:create', () => {
setupTest()
.stub(
inputUtils,
'getRawStdIn',
sandbox.stub().resolves([JSON.stringify(defaultTransaction)]),
'getStdIn',
sandbox.stub().resolves({ data: JSON.stringify(defaultTransaction) }),
)
.command(['signature:create'])
.it(
Expand Down Expand Up @@ -192,8 +192,8 @@ describe('signature:create', () => {
setupTest()
.stub(
inputUtils,
'getRawStdIn',
sandbox.stub().resolves([JSON.stringify(defaultTransaction)]),
'getStdIn',
sandbox.stub().resolves({ data: JSON.stringify(defaultTransaction) }),
)
.command(['signature:create', '--passphrase=pass:123'])
.it(
Expand Down
Loading