diff --git a/packages/printer/src/formatters/arrayFormatter.test.ts b/packages/printer/src/formatters/arrayFormatter.test.ts index 5489b62..323d4d3 100644 --- a/packages/printer/src/formatters/arrayFormatter.test.ts +++ b/packages/printer/src/formatters/arrayFormatter.test.ts @@ -23,6 +23,7 @@ const makeCtx = ( colorConfig: colorlessConfig, seen: new WeakSet(), quotes: '"', + keys: [], prefix: '', } } diff --git a/packages/printer/src/formatters/objectFormatter.test.ts b/packages/printer/src/formatters/objectFormatter.test.ts index 477e468..8c973d9 100644 --- a/packages/printer/src/formatters/objectFormatter.test.ts +++ b/packages/printer/src/formatters/objectFormatter.test.ts @@ -23,6 +23,7 @@ const makeCtx = ( colorConfig: colorlessConfig, seen: new WeakSet(), quotes: '"', + keys: [], prefix: '', } } @@ -118,4 +119,20 @@ b: 2`) // Entries still present expect(out).toContain('"a": 1') }) + + it('tracks keys in context during formatting', () => { + const ctx = makeCtx() + const recorder: string[] = [] + const numberFormatter = { + canFormat: (value: unknown) => typeof value === 'number', + format: (value: unknown, ctx: PrintContext) => { + recorder.push(ctx.keys.join('.')) + return String(value) + }, + } + const printer = new Printer([new ObjectFormatter(), numberFormatter]) + printer.print({ a: { b: 1 }, c: 2 }, ctx) + expect(recorder).toEqual(['a.b', 'c']) + expect(ctx.keys).toEqual([]) + }) }) diff --git a/packages/printer/src/formatters/objectFormatter.ts b/packages/printer/src/formatters/objectFormatter.ts index 1856be7..eedcf0a 100644 --- a/packages/printer/src/formatters/objectFormatter.ts +++ b/packages/printer/src/formatters/objectFormatter.ts @@ -48,9 +48,12 @@ export class ObjectFormatter implements IFormatter { const orgIndent = ctx.indent ctx.indent += ' '.repeat(orgPrefix.length) ctx.prefix = '' - const entries = displayed.map((k) => - getText(ctx, this.formatEntry(k, obj[k], ctx, printer)) - ) + const entries = displayed.map((k) => { + ctx.keys.push(k) + const entry = getText(ctx, this.formatEntry(k, obj[k], ctx, printer)) + ctx.keys.pop() + return entry + }) const remaining = ordered.length - displayed.length if (remaining > 0) { diff --git a/packages/printer/src/print.ts b/packages/printer/src/print.ts index 97c93d0..0c58c30 100644 --- a/packages/printer/src/print.ts +++ b/packages/printer/src/print.ts @@ -29,6 +29,7 @@ export function print( indentString, colorConfig: mergedColors, quotes: options?.quotes ?? '"', + keys: [], prefix: '', } return printer.print(value, ctx) diff --git a/packages/printer/src/printContext.ts b/packages/printer/src/printContext.ts index 3d3838b..10feb12 100644 --- a/packages/printer/src/printContext.ts +++ b/packages/printer/src/printContext.ts @@ -40,6 +40,11 @@ export interface PrintContext { */ quotes: string + /** + * Stack of object keys representing the current traversal path. + */ + keys: string[] + /** * Prefix inserted before each line when printing multi-line values * (useful for nested or list items).