Skip to content

Commit ff5f04f

Browse files
committed
properly handle ESC and Ctrl-C on prompts
1 parent f6079a6 commit ff5f04f

File tree

5 files changed

+136
-112
lines changed

5 files changed

+136
-112
lines changed

packages/cli/src/commands/add.ts

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -103,21 +103,23 @@ export default class AddCommand extends Command {
103103
} catch (error) {
104104
// we cannot ask user to do prompt in test environment
105105
if (process.env.NODE_ENV !== 'test') {
106-
const { abi: abiFile } = await prompt.ask<{ abi: string }>([
107-
{
108-
type: 'input',
109-
name: 'abi',
110-
message: 'ABI file (path)',
111-
validate: async (value: string) => {
112-
try {
113-
EthereumABI.load(contractName, value);
114-
return true;
115-
} catch (e) {
116-
return `Failed to load ABI from ${value}: ${e.message}`;
117-
}
106+
const { abi: abiFile } = await prompt
107+
.ask<{ abi: string }>([
108+
{
109+
type: 'input',
110+
name: 'abi',
111+
message: 'ABI file (path)',
112+
validate: async (value: string) => {
113+
try {
114+
EthereumABI.load(contractName, value);
115+
return true;
116+
} catch (e) {
117+
return `Failed to load ABI from ${value}: ${e.message}`;
118+
}
119+
},
118120
},
119-
},
120-
]);
121+
])
122+
.catch(() => this.exit(1)); // properly handle ESC
121123
ethabi = EthereumABI.load(contractName, abiFile);
122124
}
123125
}
@@ -130,18 +132,20 @@ export default class AddCommand extends Command {
130132
// we cannot ask user to do prompt in test environment
131133
if (process.env.NODE_ENV !== 'test') {
132134
// If we can't get the start block, we'll just leave it out of the manifest
133-
const { startBlock: userInputStartBlock } = await prompt.ask<{ startBlock: string }>([
134-
{
135-
type: 'input',
136-
name: 'startBlock',
137-
message: 'Start Block',
138-
initial: '0',
139-
validate: value => parseInt(value) >= 0,
140-
result(value) {
141-
return value;
135+
const { startBlock: userInputStartBlock } = await prompt
136+
.ask<{ startBlock: string }>([
137+
{
138+
type: 'input',
139+
name: 'startBlock',
140+
message: 'Start Block',
141+
initial: '0',
142+
validate: value => parseInt(value) >= 0,
143+
result(value) {
144+
return value;
145+
},
142146
},
143-
},
144-
]);
147+
])
148+
.catch(() => this.exit(1));
145149
startBlock = userInputStartBlock;
146150
}
147151
}
@@ -155,18 +159,20 @@ export default class AddCommand extends Command {
155159
} catch (error) {
156160
// not asking user to do prompt in test environment
157161
if (process.env.NODE_ENV !== 'test') {
158-
const { contractName: userInputContractName } = await prompt.ask<{ contractName: string }>([
159-
{
160-
type: 'input',
161-
name: 'contractName',
162-
message: 'Contract Name',
163-
initial: 'Contract',
164-
validate: value => value && value.length > 0,
165-
result(value) {
166-
return value;
162+
const { contractName: userInputContractName } = await prompt
163+
.ask<{ contractName: string }>([
164+
{
165+
type: 'input',
166+
name: 'contractName',
167+
message: 'Contract Name',
168+
initial: 'Contract',
169+
validate: value => value && value.length > 0,
170+
result(value) {
171+
return value;
172+
},
167173
},
168-
},
169-
]);
174+
])
175+
.catch(() => this.exit(1));
170176
contractName = userInputContractName;
171177
}
172178
}

packages/cli/src/commands/auth.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,20 @@ export default class AuthCommand extends Command {
2828

2929
const { node } = chooseNodeUrl({});
3030

31-
const { deployKey } = await prompt.ask<{ deployKey: string }>([
32-
{
33-
type: 'input',
34-
name: 'deployKey',
35-
message: () => 'What is your Subgraph Studio deploy key?',
36-
required: true,
37-
initial: initialDeployKey,
38-
skip: this.validateStudioDeployKey(initialDeployKey),
39-
validate: value =>
40-
this.validateStudioDeployKey(value) || `Invalid Subgraph Studio deploy key: ${value}`,
41-
},
42-
]);
31+
const { deployKey } = await prompt
32+
.ask<{ deployKey: string }>([
33+
{
34+
type: 'input',
35+
name: 'deployKey',
36+
message: () => 'What is your Subgraph Studio deploy key?',
37+
required: true,
38+
initial: initialDeployKey,
39+
skip: this.validateStudioDeployKey(initialDeployKey),
40+
validate: value =>
41+
this.validateStudioDeployKey(value) || `Invalid Subgraph Studio deploy key: ${value}`,
42+
},
43+
])
44+
.catch(() => this.exit(1));
4345

4446
try {
4547
await saveDeployKey(node!, deployKey);

packages/cli/src/commands/deploy.ts

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,18 @@ export default class DeployCommand extends Command {
111111
},
112112
} = await this.parse(DeployCommand);
113113

114-
const { subgraphName } = await prompt.ask<{ subgraphName: string }>([
115-
{
116-
type: 'input',
117-
name: 'subgraphName',
118-
message: () => 'What is the subgraph name?',
119-
skip: () => !!subgraphNameArg,
120-
initial: subgraphNameArg,
121-
required: true,
122-
},
123-
]);
114+
const { subgraphName } = await prompt
115+
.ask<{ subgraphName: string }>([
116+
{
117+
type: 'input',
118+
name: 'subgraphName',
119+
message: () => 'What is the subgraph name?',
120+
skip: () => !!subgraphNameArg,
121+
initial: subgraphNameArg,
122+
required: true,
123+
},
124+
])
125+
.catch(() => this.exit(1));
124126

125127
const { node } = chooseNodeUrl({
126128
node: nodeFlag,
@@ -153,16 +155,18 @@ export default class DeployCommand extends Command {
153155
}
154156

155157
// Ask for label if not on hosted service
156-
const { versionLabel } = await prompt.ask<{ versionLabel: string }>([
157-
{
158-
type: 'input',
159-
name: 'versionLabel',
160-
message: () => 'Which version label to use? (e.g. "v0.0.1")',
161-
initial: versionLabelFlag,
162-
skip: () => !!versionLabelFlag,
163-
required: true,
164-
},
165-
]);
158+
const { versionLabel } = await prompt
159+
.ask<{ versionLabel: string }>([
160+
{
161+
type: 'input',
162+
name: 'versionLabel',
163+
message: () => 'Which version label to use? (e.g. "v0.0.1")',
164+
initial: versionLabelFlag,
165+
skip: () => !!versionLabelFlag,
166+
required: true,
167+
},
168+
])
169+
.catch(() => this.exit(1));
166170

167171
const deploySubgraph = async (ipfsHash: string) => {
168172
const spinner = print.spin(`Deploying to Graph node ${requestUrl}`);

packages/cli/src/commands/init.ts

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -253,10 +253,12 @@ export default class InitCommand extends Command {
253253
}
254254

255255
if (fromExample) {
256-
const answers = await processFromExampleInitForm.bind(this)({
257-
subgraphName,
258-
directory,
259-
});
256+
const answers = await processFromExampleInitForm
257+
.bind(this)({
258+
subgraphName,
259+
directory,
260+
})
261+
.catch(() => this.exit(1));
260262

261263
if (!answers) {
262264
this.exit(1);
@@ -274,19 +276,21 @@ export default class InitCommand extends Command {
274276
);
275277
} else {
276278
// Otherwise, take the user through the interactive form
277-
const answers = await processInitForm.bind(this)({
278-
abi,
279-
abiPath,
280-
directory,
281-
source: fromContract,
282-
indexEvents,
283-
fromExample,
284-
subgraphName,
285-
contractName,
286-
startBlock,
287-
spkgPath,
288-
ipfsUrl: ipfs,
289-
});
279+
const answers = await processInitForm
280+
.bind(this)({
281+
abi,
282+
abiPath,
283+
directory,
284+
source: fromContract,
285+
indexEvents,
286+
fromExample,
287+
subgraphName,
288+
contractName,
289+
startBlock,
290+
spkgPath,
291+
ipfsUrl: ipfs,
292+
})
293+
.catch(() => this.exit(1));
290294
if (!answers) {
291295
this.exit(1);
292296
}
@@ -966,12 +970,13 @@ async function initSubgraphFromExample(
966970
};
967971
},
968972
) {
969-
let overwrite = false;
970973
if (filesystem.exists(directory)) {
971-
overwrite = await prompt.confirm(
972-
'Directory already exists, do you want to initialize the subgraph here (files will be overwritten) ?',
973-
false,
974-
);
974+
const overwrite = await prompt
975+
.confirm(
976+
'Directory already exists, do you want to initialize the subgraph here (files will be overwritten) ?',
977+
false,
978+
)
979+
.catch(() => false);
975980

976981
if (!overwrite) {
977982
this.exit(1);
@@ -1005,7 +1010,7 @@ async function initSubgraphFromExample(
10051010
return { result: false, error: `Example not found: ${fromExample}` };
10061011
}
10071012

1008-
filesystem.copy(exampleSubgraphPath, directory, { overwrite });
1013+
filesystem.copy(exampleSubgraphPath, directory, { overwrite: true });
10091014
return true;
10101015
} finally {
10111016
filesystem.remove(tmpDir);
@@ -1129,14 +1134,17 @@ async function initSubgraphFromContract(
11291134
},
11301135
) {
11311136
const isComposedSubgraph = protocolInstance.isComposedSubgraph();
1132-
if (
1133-
filesystem.exists(directory) &&
1134-
!(await prompt.confirm(
1135-
'Directory already exists, do you want to initialize the subgraph here (files will be overwritten) ?',
1136-
false,
1137-
))
1138-
) {
1139-
this.exit(1);
1137+
if (filesystem.exists(directory)) {
1138+
const overwrite = await prompt
1139+
.confirm(
1140+
'Directory already exists, do you want to initialize the subgraph here (files will be overwritten) ?',
1141+
false,
1142+
)
1143+
.catch(() => false);
1144+
1145+
if (!overwrite) {
1146+
this.exit(1);
1147+
}
11401148
}
11411149

11421150
let entities: string[] | undefined;
@@ -1232,10 +1240,12 @@ async function initSubgraphFromContract(
12321240
}
12331241

12341242
while (addContract) {
1235-
addContract = await addAnotherContract.bind(this)({
1236-
protocolInstance,
1237-
directory,
1238-
});
1243+
addContract = await addAnotherContract
1244+
.bind(this)({
1245+
protocolInstance,
1246+
directory,
1247+
})
1248+
.catch(() => false);
12391249
}
12401250
}
12411251

packages/cli/src/commands/publish.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,17 @@ export default class PublishCommand extends Command {
6767
protocolNetwork: string | undefined;
6868
apiKey: string | undefined;
6969
}) {
70-
const { openBrowser } = await prompt.ask<{ openBrowser: boolean }>([
71-
{
72-
type: 'confirm',
73-
name: 'openBrowser',
74-
message: () => `Open up the browser to continue publishing ?`,
75-
initial: true,
76-
required: true,
77-
},
78-
]);
70+
const { openBrowser } = await prompt
71+
.ask<{ openBrowser: boolean }>([
72+
{
73+
type: 'confirm',
74+
name: 'openBrowser',
75+
message: () => `Open up the browser to continue publishing ?`,
76+
initial: true,
77+
required: true,
78+
},
79+
])
80+
.catch(() => this.exit(1));
7981

8082
if (!openBrowser) {
8183
this.exit(0);

0 commit comments

Comments
 (0)