Skip to content

Commit 22ff4cb

Browse files
fix(cli): preserve hex positional args as strings by re-parsing argv (#1188)
1 parent 62b476c commit 22ff4cb

13 files changed

Lines changed: 63 additions & 17 deletions

File tree

packages/indexer-cli/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,14 @@
3939
"isomorphic-fetch": "3.0.0",
4040
"table": "6.7.5",
4141
"yaml": "1.10.2",
42-
"wrap-ansi": "7.0.0"
42+
"wrap-ansi": "7.0.0",
43+
"yargs-parser": "21.1.1"
4344
},
4445
"devDependencies": {
4546
"@types/isomorphic-fetch": "0.0.36",
4647
"@types/lodash.clonedeep": "^4.5.7",
4748
"@types/wrap-ansi": "3.0.0",
49+
"@types/yargs-parser": "21.0.3",
4850
"@typescript-eslint/eslint-plugin": "6.7.0",
4951
"@typescript-eslint/parser": "6.7.0",
5052
"eslint": "8.49.0",

packages/indexer-cli/src/command-helpers.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import { table, getBorderCharacters } from 'table'
3030
import wrapAnsi from 'wrap-ansi'
31+
import yargsParse from 'yargs-parser'
3132

3233
export enum OutputFormat {
3334
Table = 'table',
@@ -64,6 +65,27 @@ export const fixParameters = (
6465
}
6566
}
6667

68+
/**
69+
* Re-parses process.argv with number parsing disabled to recover positional
70+
* arguments as strings. gluegun uses yargs-parser internally and converts hex
71+
* strings (e.g. 0x0, 0x...0010) to numbers before our commands see them,
72+
* making the conversion irreversible. Re-parsing with 'parse-numbers: false'
73+
* and taking the last N positionals (N = parametersArray.length) restores
74+
* the original strings, since gluegun strips the subcommand prefix from
75+
* parameters.array but our re-parse includes it.
76+
*/
77+
export function getRawPositionalArgs(parametersArray: unknown[]): string[] {
78+
const raw = yargsParse(process.argv.slice(2), {
79+
configuration: { 'parse-numbers': false },
80+
})
81+
// raw._ includes the full subcommand path (e.g. ['indexer', 'allocations', 'close', ...])
82+
// while parameters.array has already had the command path stripped by gluegun.
83+
// Taking the last N elements (N = parameters.array.length) removes the command path
84+
// and gives us only the user-provided positional arguments.
85+
const positionals = raw._ as string[]
86+
return positionals.slice(positionals.length - parametersArray.length)
87+
}
88+
6789
export const formatData = (
6890
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
6991
data: any,

packages/indexer-cli/src/commands/indexer/actions/queue.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { createIndexerManagementClient } from '../../../client'
66
import {
77
requireProtocolNetworkOption,
88
printObjectOrArray,
9+
getRawPositionalArgs,
910
} from '../../../command-helpers'
1011
import { buildActionInput, queueActions, validateActionType } from '../../../actions'
1112
import {
@@ -67,7 +68,7 @@ module.exports = {
6768
}
6869

6970
const [type, targetDeployment, param1, param2, param3, param4, param5, param6] =
70-
parameters.array || []
71+
getRawPositionalArgs(parameters.array || [])
7172

7273
let actionInputParams: ActionInput
7374
try {

packages/indexer-cli/src/commands/indexer/allocations/close.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
validatePOI,
99
printObjectOrArray,
1010
extractProtocolNetworkOption,
11+
getRawPositionalArgs,
1112
} from '../../../command-helpers'
1213

1314
const HELP = `
@@ -58,7 +59,7 @@ module.exports = {
5859
}
5960

6061
const [id, unformattedPoi, unformattedBlockNumber, unformattedPublicPOI] =
61-
parameters.array || []
62+
getRawPositionalArgs(parameters.array || [])
6263

6364
if (id === undefined) {
6465
spinner.fail(`Missing required argument: 'id'`)

packages/indexer-cli/src/commands/indexer/allocations/collect.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import chalk from 'chalk'
44
import { loadValidatedConfig } from '../../../config'
55
import { createIndexerManagementClient } from '../../../client'
66
import { submitCollectReceiptsJob } from '../../../allocations'
7-
import { extractProtocolNetworkOption } from '../../../command-helpers'
7+
import {
8+
extractProtocolNetworkOption,
9+
getRawPositionalArgs,
10+
} from '../../../command-helpers'
811

912
const HELP = `
1013
${chalk.bold('graph indexer allocations collect')} [options] <network> <id>
@@ -41,7 +44,7 @@ module.exports = {
4144
return
4245
}
4346

44-
const [id] = parameters.array || []
47+
const [id] = getRawPositionalArgs(parameters.array || [])
4548

4649
if (id === undefined) {
4750
spinner.fail(`Missing required argument: 'id'`)

packages/indexer-cli/src/commands/indexer/allocations/create.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { processIdentifier, SubgraphIdentifierType } from '@graphprotocol/indexe
88
import {
99
extractProtocolNetworkOption,
1010
printObjectOrArray,
11+
getRawPositionalArgs,
1112
} from '../../../command-helpers'
1213

1314
const HELP = `
@@ -49,7 +50,7 @@ module.exports = {
4950
return
5051
}
5152

52-
const [deploymentID, amount, indexNode] = parameters.array || []
53+
const [deploymentID, amount, indexNode] = getRawPositionalArgs(parameters.array || [])
5354

5455
try {
5556
const protocolNetwork = extractProtocolNetworkOption(parameters.options, true)

packages/indexer-cli/src/commands/indexer/allocations/present-poi.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
extractProtocolNetworkOption,
99
printObjectOrArray,
1010
validatePOI,
11+
getRawPositionalArgs,
1112
} from '../../../command-helpers'
1213

1314
const HELP = `
@@ -62,7 +63,7 @@ module.exports = {
6263
}
6364

6465
const [id, unformattedPoi, unformattedBlockNumber, unformattedPublicPOI] =
65-
parameters.array || []
66+
getRawPositionalArgs(parameters.array || [])
6667

6768
if (id === undefined) {
6869
spinner.fail(`Missing required argument: 'id'`)

packages/indexer-cli/src/commands/indexer/allocations/reallocate.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
extractProtocolNetworkOption,
99
printObjectOrArray,
1010
validatePOI,
11+
getRawPositionalArgs,
1112
} from '../../../command-helpers'
1213

1314
const HELP = `
@@ -57,8 +58,9 @@ module.exports = {
5758
return
5859
}
5960

60-
// eslint-disable-next-line prefer-const
61-
let [id, amount, poi, unformattedBlockNumber, publicPOI] = parameters.array || []
61+
const [id, amount, poi, unformattedBlockNumber, publicPOI] = getRawPositionalArgs(
62+
parameters.array || [],
63+
)
6264

6365
if (id === undefined) {
6466
spinner.fail(`Missing required argument: 'id'`)

packages/indexer-cli/src/commands/indexer/allocations/resize.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { resizeAllocation } from '../../../allocations'
77
import {
88
extractProtocolNetworkOption,
99
printObjectOrArray,
10+
getRawPositionalArgs,
1011
} from '../../../command-helpers'
1112

1213
const HELP = `
@@ -54,7 +55,7 @@ module.exports = {
5455
return
5556
}
5657

57-
const [id, amount] = parameters.array || []
58+
const [id, amount] = getRawPositionalArgs(parameters.array || [])
5859

5960
if (id === undefined) {
6061
spinner.fail(`Missing required argument: 'id'`)

packages/indexer-cli/src/commands/indexer/disputes/get.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import chalk from 'chalk'
44
import { loadValidatedConfig } from '../../../config'
55
import { createIndexerManagementClient } from '../../../client'
66
import { disputes, printDisputes } from '../../../disputes'
7-
import { parseOutputFormat, extractProtocolNetworkOption } from '../../../command-helpers'
7+
import {
8+
parseOutputFormat,
9+
extractProtocolNetworkOption,
10+
getRawPositionalArgs,
11+
} from '../../../command-helpers'
812

913
const HELP = `
1014
${chalk.bold(
@@ -26,7 +30,9 @@ module.exports = {
2630
const { print, parameters } = toolbox
2731

2832
const { h, help, o, output } = parameters.options
29-
const [status, minAllocationClosedEpoch] = parameters.array || []
33+
const [status, minAllocationClosedEpoch] = getRawPositionalArgs(
34+
parameters.array || [],
35+
)
3036
const outputFormat = parseOutputFormat(print, o || output || 'table')
3137

3238
if (help || h) {

0 commit comments

Comments
 (0)