Skip to content

Commit a84fe2b

Browse files
fix: improve filterFields heuristic and maxLines nullish check (DIS-145)
- filterFields now checks if any requested field matches a top-level key. If yes, picks from top level (handles Collection with array props like contracts, editors). If no match, treats as wrapper and filters array items (handles {nfts: [...], next: ...} responses). - Changed maxLines guard from truthiness to != null so --max-lines 0 works. - Added tests for objects with array properties and maxLines 0. Co-Authored-By: Chris K <ckorhonen@gmail.com>
1 parent 06aaf5b commit a84fe2b

2 files changed

Lines changed: 41 additions & 15 deletions

File tree

src/output.ts

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export function formatOutput(data: unknown, format: OutputFormat): string {
2727
result = JSON.stringify(processed, null, 2)
2828
}
2929

30-
if (_outputOptions.maxLines) {
30+
if (_outputOptions.maxLines != null) {
3131
result = truncateOutput(result, _outputOptions.maxLines)
3232
}
3333

@@ -99,21 +99,23 @@ function filterFields(data: unknown, fields: string[]): unknown {
9999
}
100100
if (data && typeof data === "object") {
101101
const obj = data as Record<string, unknown>
102-
const arrayKeys = Object.keys(obj).filter(k => Array.isArray(obj[k]))
103-
if (arrayKeys.length > 0) {
104-
const result: Record<string, unknown> = {}
105-
for (const [key, value] of Object.entries(obj)) {
106-
result[key] = Array.isArray(value)
107-
? value.map(item =>
108-
item && typeof item === "object"
109-
? pickFields(item as Record<string, unknown>, fields)
110-
: item,
111-
)
112-
: value
113-
}
114-
return result
102+
const keys = Object.keys(obj)
103+
const hasMatchingKey = fields.some(f => f in obj)
104+
if (hasMatchingKey) {
105+
return pickFields(obj, fields)
115106
}
116-
return pickFields(obj, fields)
107+
const result: Record<string, unknown> = {}
108+
for (const key of keys) {
109+
const value = obj[key]
110+
result[key] = Array.isArray(value)
111+
? value.map(item =>
112+
item && typeof item === "object"
113+
? pickFields(item as Record<string, unknown>, fields)
114+
: item,
115+
)
116+
: value
117+
}
118+
return result
117119
}
118120
return data
119121
}

test/output.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,23 @@ describe("formatOutput", () => {
132132
expect(result).toEqual({ name: "test" })
133133
})
134134

135+
it("filters top-level fields on objects with array properties", () => {
136+
setOutputOptions({ fields: ["name", "collection"] })
137+
const data = {
138+
name: "Cool Cats",
139+
collection: "cool-cats",
140+
description: "A cool collection",
141+
contracts: [{ address: "0x1", chain: "ethereum" }],
142+
editors: ["alice"],
143+
fees: [{ fee: 250, recipient: "0x2", required: true }],
144+
}
145+
const result = JSON.parse(formatOutput(data, "json"))
146+
expect(result).toEqual({
147+
name: "Cool Cats",
148+
collection: "cool-cats",
149+
})
150+
})
151+
135152
it("returns primitives unchanged", () => {
136153
setOutputOptions({ fields: ["name"] })
137154
expect(formatOutput("hello", "json")).toBe('"hello"')
@@ -183,6 +200,13 @@ describe("formatOutput", () => {
183200
expect(lines).toHaveLength(3)
184201
expect(lines[2]).toMatch(/\.\.\. \(\d+ more lines?\)/)
185202
})
203+
204+
it("handles max-lines 0 by truncating all lines", () => {
205+
setOutputOptions({ maxLines: 0 })
206+
const data = { a: 1 }
207+
const result = formatOutput(data, "json")
208+
expect(result).toContain("... (3 more lines)")
209+
})
186210
})
187211

188212
describe("--fields and --max-lines combined", () => {

0 commit comments

Comments
 (0)